Stream流根据属性去重

科技资讯 投稿 5400 0 评论

Stream流根据属性去重

List根据属性去重

 User user1 = new User("user1", 18, "AAA";
        User user2 = new User("user2", 18, "BBB";
        User user3 = new User("user3", 18, "AAA";
        User user4 = new User("user4", 75, "CCC";
        User user5 = new User("user5", 35, "AAA";

        ArrayList<User> list = new ArrayList<>(;
        list.add(user1;
        list.add(user2;
        list.add(user3;
        list.add(user4;
        list.add(user5;

自定义Predict函数,使用filter(

写一个Predict
public class DistinctKeyUtil {
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor {
        ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>(;
        return t -> map.putIfAbsent(keyExtractor.apply(t, Boolean.TRUE == null;
    }
}
使用filter方法
/**
* 写一个Predict进行属性过滤
*/
//先过滤age在过滤hobby
List<User> result = list.stream(
.filter(DistinctKeyUtil.distinctByKey(n -> n.getAge(
.filter(DistinctKeyUtil.distinctByKey(n -> n.getHobby(
.collect(Collectors.toList(;

result.forEach(System.out::println;
结果:
User{name='user1', age=18, hobby='AAA'}
User{name='user4', age=75, hobby='CCC'}
小结:

实质上是将每个元素都放到distinctByKey(中的ConcurrentHashMap作为key进行过滤,如果key不存在那么就加上去,如果已经存在了就不加。所以这种方式的过滤只保留第一个重复元素。

利用TreeSet

        //过滤age
        ArrayList<User> result2 = list.stream(.collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(
                                ( -> new TreeSet<>(Comparator.comparing(o -> o.getAge(, ArrayList::new;
								
        result2.forEach(System.out::println;

结果与上面的一样

同时过滤两个属性

        //age和hobby一起过滤
        ArrayList<User> result1 = list.stream(.collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(
                                ( -> new TreeSet<>(Comparator.comparing(o -> o.getHobby( + ";" + o.getAge(, ArrayList::new
        ;
        result1.forEach(System.out::println;
结果:
User{name='user1', age=18, hobby='AAA'}
User{name='user5', age=35, hobby='AAA'}
User{name='user2', age=18, hobby='BBB'}
User{name='user4', age=75, hobby='CCC'}
小结:

TreeSet存储唯一的元素,并且按升序对元素进行排序。

Map:保证Key的唯一性

        /**
         * map 根据某属性过滤
         */
        //  Function.identity( 相等于  o->o
        Map<String, User> map1 = list.stream(.collect(Collectors.toMap(User::getHobby, Function.identity(, (t1, t2 -> t1;
        Set<Map.Entry<String, User>> entries1 = map1.entrySet(;
        entries1.forEach(System.out::println;
结果:
AAA=User{name='user1', age=18, hobby='AAA'}
CCC=User{name='user4', age=75, hobby='CCC'}
BBB=User{name='user2', age=18, hobby='BBB'}
小结:

map可以选择保留重复属性中的前一条数据还是后一条:(t1, t2 -> t1

编程笔记 » Stream流根据属性去重

赞同 (27) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽