首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8并行流并发分组

Java 8并行流并发分组
EN

Stack Overflow用户
提问于 2017-12-16 18:20:21
回答 2查看 6.1K关注 0票数 7

假设我有一个类

代码语言:javascript
复制
Class Person {
  String name;
  String uid;
  String phone;
}

我正试着按全班的所有字段分组。如何使用JAVA 8中的并行流来转换

代码语言:javascript
复制
List<Person> into Map<String,Set<Person>>

其中,映射的键是类中每个字段的值。以下示例按单个字段分组,如何将类的所有字段组合成单个Map?

代码语言:javascript
复制
ConcurrentMap<Person.Sex, List<Person>> byGender =
roster
    .parallelStream()
    .collect(
        Collectors.groupingByConcurrent(Person::getGender));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-16 18:46:02

您可以通过使用来自ofCollector的静态工厂方法来实现这一点。

代码语言:javascript
复制
Map<String, Set<Person>> groupBy = persons.parallelStream()
    .collect(Collector.of(
        ConcurrentHashMap::new,
        ( map, person ) -> {
            map.computeIfAbsent(person.name, k -> new HashSet<>()).add(person);
            map.computeIfAbsent(person.uid, k -> new HashSet<>()).add(person);
            map.computeIfAbsent(person.phone, k -> new HashSet<>()).add(person);
        },
        ( a, b ) -> {
            b.forEach(( key, set ) -> a.computeIfAbsent(key, k -> new HashSet<>()).addAll(set));
            return a;
        }
    ));

正如霍尔格在评论中所建议的那样,以下方法比上面的方法更可取:

代码语言:javascript
复制
Map<String, Set<Person>> groupBy = persons.parallelStream()
     .collect(HashMap::new, (m, p) -> { 
         m.computeIfAbsent(p.name, k -> new HashSet<>()).add(p); 
         m.computeIfAbsent(p.uid, k -> new HashSet<>()).add(p); 
         m.computeIfAbsent(p.phone, k -> new HashSet<>()).add(p); 
     }, (a, b) -> b.forEach((key, set) -> {
         a.computeIfAbsent(key, k -> new HashSet<>()).addAll(set));
     });

它使用重载的collect方法,它的行为与我上面建议的语句相同。

票数 5
EN

Stack Overflow用户

发布于 2017-12-16 18:29:33

您可以连锁您的分组收集器,这将给您一个多层次的地图。但是,如果您想按两个以上的字段进行分组,这是不理想的。

更好的选择是覆盖equalshashcode类中的Person方法,以定义两个给定对象的相等,在本例中,这些对象就是所有上述字段。然后您可以按Person i.e groupingByConcurrent(Function.identity())进行分组,在这种情况下,您将得到以下结果:

代码语言:javascript
复制
ConcurrentMap<Person, List<Person>> resultSet = ....

示例:

代码语言:javascript
复制
class Person {
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (name != null ? !name.equals(person.name) : person.name != null) return false;
        if (uid != null ? !uid.equals(person.uid) : person.uid != null) return false;
        return phone != null ? phone.equals(person.phone) : person.phone == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (uid != null ? uid.hashCode() : 0);
        result = 31 * result + (phone != null ? phone.hashCode() : 0);
        return result;
    }

    private String name;
    private String uid; // these should be private, don't expose
    private String phone;

   // getters where necessary
   // setters where necessary
}

然后:

代码语言:javascript
复制
ConcurrentMap<Person, List<Person>> resultSet = list.parallelStream()
                .collect(Collectors.groupingByConcurrent(Function.identity()));
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47848696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档