简体   繁体   English

在条件下使用Java 8 groupBy

[英]using java 8 groupBy with conditions

  1. Group by number to find groups with size bigger then 1 2. Check if a group contains a condition (string !=null) 按数字分组以查找大小大于1的分组2.检查一个分组是否包含条件(字符串!= null)

     2a. if yes ---> remove all rows which do not have a condition (string == null) 2b. if no ---> return the group as it is (no filtering at all) 

I am trying below code but I am not able to filter the condition here. 我正在尝试下面的代码,但无法在此处过滤条件。 Is there any simple way to do it? 有什么简单的方法吗?

groupByList = list.stream().collect(Collectors.groupingBy(student::no));
groupByList.values().stream().map(group -> group.size() > 1)
                 .collect(Collectors.toList());

You need to use both Stream.filter(..) and Stream.map(..) 您需要同时使用Stream.filter(..)和Stream.map(..)

// Groups students by group number
Map<String, List<Student>> allGroups = list.stream().collect(Collectors.groupingBy(student::no));
// Filters groups that have more than 1 member
Map<String, List<Student>> filteredGroups = allGroups.entrySet().stream().filter(entry -> entry.getValue().size() > 1).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
// Removes all non-null members
Map<String, List<Student>> cleanGroups = filteredGroups.entrySet().stream()
    .map(entry -> {
        entry.setValue(entry.getValue().stream().filter(student -> student.name != null).collect(Collectors.toList()));
        return entry;
    }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

You can pipe the execution into one big chain: 您可以将执行分成一个大链:

Map<String, List<Student>> cleanGroups = list.stream()
      .collect(Collectors.groupingBy(student::no))
      .entrySet().stream()
      .filter(entry -> entry.getValue().size() > 1)
      .map(entry -> {
         entry.setValue(entry.getValue().stream()
                             .filter(student -> student.name != null)
                             .collect(Collectors.toList()));
        return entry;
      })
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Please note, that you have a hidden object transformation withing the .filter(..).collect(..) above. 请注意,上面的.filter(..)。collect(..)具有隐藏的对象转换。 If you need to skip that (at cost of double comparison), you can extend the lambda method to: 如果您需要跳过该步骤(以双重比较为代价),则可以将lambda方法扩展为:

 .map(entry -> {
     if (entry.getValue().stream.anyMatch(student.name == null)) {
        entry.setValue(entry.getValue().stream().filter(student -> student.name != null).collect(Collectors.toList()));
     }
     return entry;
 })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM