Java 8 Distinct by property

后端 未结 29 2261
傲寒
傲寒 2020-11-21 22:35

In Java 8 how can I filter a collection using the Stream API by checking the distinctness of a property of each object?

For example I have a list of

29条回答
  •  一整个雨季
    2020-11-21 23:11

    A variation of the top answer that handles null:

        public static  Predicate distinctBy(final Function getKey) {
            val seen = ConcurrentHashMap.>newKeySet();
            return obj -> seen.add(Optional.ofNullable(getKey.apply(obj)));
        }
    

    In my tests:

            assertEquals(
                    asList("a", "bb"),
                    Stream.of("a", "b", "bb", "aa").filter(distinctBy(String::length)).collect(toList()));
    
            assertEquals(
                    asList(5, null, 2, 3),
                    Stream.of(5, null, 2, null, 3, 3, 2).filter(distinctBy(x -> x)).collect(toList()));
    
            val maps = asList(
                    hashMapWith(0, 2),
                    hashMapWith(1, 2),
                    hashMapWith(2, null),
                    hashMapWith(3, 1),
                    hashMapWith(4, null),
                    hashMapWith(5, 2));
    
            assertEquals(
                    asList(0, 2, 3),
                    maps.stream()
                            .filter(distinctBy(m -> m.get("val")))
                            .map(m -> m.get("i"))
                            .collect(toList()));
    

提交回复
热议问题