map根据条件收集不同的值

umuewwlo  于 2021-07-08  发布在  Java
关注(0)|答案(4)|浏览(329)

这个问题在这里已经有答案了

java 8 tomap illegalstateexception重复键(2个答案)
上个月关门了。
我试图将列表收集到Map中,但列表对象中有重复的条目。
所以假设我有 aList 我身上有什么
[{1,“.jpg”},{2,“bcd.png”},{1,“mno.jpg”},{3,“.jpg”},{1,null},{1,“}]
现在在上面的列表中,您可以看到1在重复时具有不同的值。
我想收集到Map上提供的上述名单只有当它有一些价值。
像在上面的集合你可能会有问题,如果我找到不同的,然后收集他们分组填充值将挑选我的答案是任何填充值是必需的,但不是空的,空格或空。
所以任何人都可以没事,除了三种情况:空、空白或空。
我只想在我的列表中设置id是否有任何图像,因此只检查空、空白或null。
输出(不明确):
输出1
[{1,“.jpg”},{2,“bcd.png”},{3,“.jpg”}]
输出2
[{2,“bcd.png”},{1,“mno.jpg”},{3,“.jpg”}]
以上两个列表结果都可以是map中的输出。
我的方法:

itemImageMap = imageService.findByItemUuidIn(itemUuids)
   .stream().filter(obj->(Objects.nonNull(obj)&& Objects.nonNull(obj[1])))
   .collect(Collectors.toMap(obj->String.valueOf(obj[0]), obj->String.valueOf(obj[1])));

我得到重复的密钥错误。
为了更清楚我的目的是收集这张Map。一旦我收集到Map上,我的目标就是这个=>

itemDetailsList.stream().filter(obj->itemImageMap.containsKey(obj.getItemUuid())).map(obj-> {

                String imageUrl = itemImageMap.get(obj.getItemUuid());

                if(StringUtils.isNotBlank(imageUrl))
                    obj.setShowImage(true);

                return obj;
            });

如果我有一个路径,那么设置为true,否则默认值为false。

bt1cpqcv

bt1cpqcv1#

var list = List.<Map.Entry<Integer, String>>of(
    new AbstractMap.SimpleImmutableEntry<>(1, "abc.jpg"),
    new AbstractMap.SimpleImmutableEntry<>(2, "bcd.png"),
    new AbstractMap.SimpleImmutableEntry<>(1, "mno.jpg"),
    new AbstractMap.SimpleImmutableEntry<>(3, "abc.jpg"),
    new AbstractMap.SimpleImmutableEntry<>(1, null),
    new AbstractMap.SimpleImmutableEntry<>(1, "")
);

var map = list.stream()
    .filter(it -> it.getValue() != null && !it.getValue().isEmpty())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));

System.out.println(map);

{1=.jpg,2=bcd.png,3=.jpg}
我用的是Java11 var 以及 List.of ,但是代码可以很容易地适应Java8。java太冗长了, new AbstractMap.SimpleImmutableEntry<>(1, ".jpg") 每次我想做一对的时候都让我头疼。

iovurdzv

iovurdzv2#

要消除重复密钥错误,请使用 toMap 第三个参数指示在重复的情况下保留哪个值。例如,要保留第一个值:

.collect(Collectors.toMap(obj->String.valueOf(obj[0]), obj->String.valueOf(obj[1]), (first, second) -> first));

但是在重复的情况下,您也可以使用键将值分组到一个列表中,而不是忽略一个值 Map<String,List<String> 而不是 Map<String,String> . 比如:

.collect(Collectors.groupingBy(obj->String.valueOf(obj[0]), 
                                   Collectors.mapping(obj->String.valueOf(obj[1]), 
                                   Collectors.toList())));
n8ghc7c1

n8ghc7c13#

如果我的想法是正确的-以下是我的答案灵感来源于这个答案:

class Data {
Integer id;
String name;

public Data(Integer id, String name) {
    this.id = id;
    this.name = name;
}

public Integer getId() {
    return id;
}

@Override
public String toString() {
    return "Data{" + "id=" + id + ", name='" + name + '\'' + '}';
}
}

public class Main {

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

public static void main(String[] args) {
    List<Data> list = List.of(new Data(1, "abc.jpg"), new Data(2, "bcd.png"), new Data(1, null));

    List<Data> result = list.stream()
                            .filter(d -> d.name != null && !d.name.equals(""))
                            .filter(distinctByKey(Data::getId))
                            .collect(Collectors.toList());

    result.forEach(System.out::println);
}

}

zbdgwd5y

zbdgwd5y4#

使用 Collectors.groupingBy 使用 getItemUuid() 后续下游的方法: Collectors.mapping 获取图像url(我假设有一个方法 MyObject#getUrl ). Collectors.filtering 要过滤掉java-9及更高版本中的无效字符串,否则需要使用 filter 在你进入 collect 方法。
java 8

Map<Integer, List<String>> map = list.stream()
    .filter(obj -> obj.getUrl() != null && !obj.getUrl().trim().isEmpty())
    .collect(Collectors.groupingBy(
            MyObject::getItemUuid,
            Collectors.mapping(MyObject::getUrl, Collectors.toList())));

java 9+

Map<Integer, List<String>> map = list.stream()
    .collect(Collectors.groupingBy(MyObject::getItemUuid,
            Collectors.mapping(MyObject::getUrl,
                    Collectors.filtering(url -> url != null && !url.trim().isEmpty(), 
                            Collectors.toList()))));

结果: {1=[.jpg, mno.jpg], 2=[bcd.png], 3=[.jpg]}

相关问题