Stream流根据属性去重

打印 上一主题 下一主题

主题 800|帖子 800|积分 2400

List根据属性去重

创建一个user集合
  1. User user1 = new User("user1", 18, "AAA");
  2.         User user2 = new User("user2", 18, "BBB");
  3.         User user3 = new User("user3", 18, "AAA");
  4.         User user4 = new User("user4", 75, "CCC");
  5.         User user5 = new User("user5", 35, "AAA");
  6.         ArrayList<User> list = new ArrayList<>();
  7.         list.add(user1);
  8.         list.add(user2);
  9.         list.add(user3);
  10.         list.add(user4);
  11.         list.add(user5);
复制代码
自定义Predict函数,使用filter()

写一个Predict
  1. public class DistinctKeyUtil {
  2.     public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
  3.         ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
  4.         return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
  5.     }
  6. }
复制代码
使用filter方法
  1. /**
  2. * 写一个Predict进行属性过滤
  3. */
  4. //先过滤age在过滤hobby
  5. List<User> result = list.stream()
  6. .filter(DistinctKeyUtil.distinctByKey(n -> n.getAge()))
  7. .filter(DistinctKeyUtil.distinctByKey(n -> n.getHobby()))
  8. .collect(Collectors.toList());
  9. result.forEach(System.out::println);
复制代码
结果:
  1. User{name='user1', age=18, hobby='AAA'}
  2. User{name='user4', age=75, hobby='CCC'}
复制代码
小结:

实质上是将每个元素都放到distinctByKey()中的ConcurrentHashMap作为key进行过滤,如果key不存在那么就加上去,如果已经存在了就不加。所以这种方式的过滤只保留第一个重复元素。
利用TreeSet
  1.         //过滤age
  2.         ArrayList<User> result2 = list.stream().collect(
  3.                 Collectors.collectingAndThen(
  4.                         Collectors.toCollection(
  5.                                 () -> new TreeSet<>(Comparator.comparing(o -> o.getAge()))), ArrayList::new));
  6.                                                                
  7.         result2.forEach(System.out::println);
复制代码
结果与上面的一样
同时过滤两个属性
  1.         //age和hobby一起过滤
  2.         ArrayList<User> result1 = list.stream().collect(
  3.                 Collectors.collectingAndThen(
  4.                         Collectors.toCollection(
  5.                                 () -> new TreeSet<>(Comparator.comparing(o -> o.getHobby() + ";" + o.getAge()))), ArrayList::new)
  6.         );
  7.         result1.forEach(System.out::println);
复制代码
结果:
  1. User{name='user1', age=18, hobby='AAA'}
  2. User{name='user5', age=35, hobby='AAA'}
  3. User{name='user2', age=18, hobby='BBB'}
  4. User{name='user4', age=75, hobby='CCC'}
复制代码
小结:

TreeSet存储唯一的元素,并且按升序对元素进行排序。
Map:保证Key的唯一性
  1.         /**
  2.          * map 根据某属性过滤
  3.          */
  4.         //  Function.identity() 相等于  o->o
  5.         Map<String, User> map1 = list.stream().collect(Collectors.toMap(User::getHobby, Function.identity(), (t1, t2) -> t1));
  6.         Set<Map.Entry<String, User>> entries1 = map1.entrySet();
  7.         entries1.forEach(System.out::println);
复制代码
结果:
  1. AAA=User{name='user1', age=18, hobby='AAA'}
  2. CCC=User{name='user4', age=75, hobby='CCC'}
  3. BBB=User{name='user2', age=18, hobby='BBB'}
复制代码
小结:

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表