zoukankan      html  css  js  c++  java
  • Lambda如何实现条件去重distinct List,如何实现条件分组groupBy List

    条件去重

    我们知道, Java8 lambda自带的去重为 distinct 方法, 但是只能过滤整体对象, 不能实现对象里的某个值进行判定去重, 比如:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 5, 5, 5, 6, 7);
    
    List<Integer> distinctNumbers = numbers.stream()
    .distinct()
    .collect(Collectors.toList());
    System.out.println(distinctNumbers);//1, 2, 3, 4, 5, 6, 7
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 5, 5, 5, 6, 7);
     
    List<Integer> distinctNumbers = numbers.stream()
    .distinct()
    .collect(Collectors.toList());
    System.out.println(distinctNumbers);//1, 2, 3, 4, 5, 6, 7
    

    但是, 如果我们有一个 List 类似这样的对象, 要对 User 的 name 进行条件去重怎么办?
    我们想要的效果是这样的:

    List<User> distinctUsers = users.stream()
    .distinct(User::getName)
    .collect(Collectors.toList());
    

    但是很遗憾, distinct()方法并不能设置条件. 解决方案如下:
    首先定义一个过滤器:

    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
    }
    

    然后就可以进行条件去重啦:

    List<User> users = new LinkedList<>();
    users.add(new User("Jim"));
    users.add(new User("Jim"));
    users.add(new User("Tom"));
    users.add(new User("Leo"));
    
    List<User> distinctUsers = users.stream()
            .filter(distinctByKey(User::getName))
            .collect(Collectors.toList());
    
    System.out.println(distinctUsers);//[Jim, Tom, Leo]
    

    条件分组

    还是一样的例子, 我们有一个 List, User 有 name 和 age. 现在我们想把这个 List 按年龄分成三组:0<age<=20, 20<age<=40, 40<age.
    直接上代码:

    List<User> users = new LinkedList<>();
    users.add(new User("Jim", 12));
    users.add(new User("John", 18));
    users.add(new User("Tom", 21));
    users.add(new User("Leo", 30));
    users.add(new User("Kate", 44));
    users.add(new User("Lio", 50));
    
    Map<String, List<User>> tripleUsers = users.stream()
            .collect(Collectors.groupingBy((Function<User, String>) user -> {
        String key;
        if (user.getAge() <= 20) {
            key = "less20";
        } else if (user.getAge() <= 40) {
            key = "less40";
        } else {
            key = "more40";
        }
        return key;
    }, Collectors.toList()));
    
    System.out.println(tripleUsers);
    //{more40=[Kate, Lio], less40=[Tom, Leo], less20=[Jim, John]}
    
  • 相关阅读:
    剑指Offer面试题:26.字符串的排列
    剑指Offer面试题:25.二叉搜索树与双向链表
    使用VS2013分析DMP文件
    目的 存在 问题 价值
    thinking models--基于事实和全方位思考
    目的-哲学解释
    亚里士多德.四因说
    存在与目的 人类与上帝
    我用过的数据库 sqlite realm mysql coredata
    swift Existential Container witness table
  • 原文地址:https://www.cnblogs.com/liuyupen/p/12335652.html
Copyright © 2011-2022 走看看