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]}
    
  • 相关阅读:
    JavaScript:Number 对象
    JavaScript:Math 对象
    杂项:引用资源列表
    小团队管理与大团队管理
    技术转管理
    【翻译+整理】.NET Core的介绍
    自己开发给自己用的个人知识管理工具【脑细胞】,源码提供
    关于【自证清白】
    这篇博客能让你戒烟——用程序员的思维来戒烟!
    如果我是博客园的产品经理【下】
  • 原文地址:https://www.cnblogs.com/liuyupen/p/12335652.html
Copyright © 2011-2022 走看看