简体   繁体   English

Java流将对象列表收集到存储桶

[英]Java streams collect list of objects to buckets

I have a problem of collecting some list values to buckets. 我在收集一些列表值到存储桶时遇到问题。 For example, let's assume I have a list of Strings: 例如,假设我有一个字符串列表:

List<String> strs = Arrays.asList("ABC", "abc", "bca", "BCa", "AbC");

And I want to put the strings into set (or list) of sets, that contain only case-different strings, ie for example above it would be collection of two sets: [["ABC", "abc", "AbC"], ["bca", "BCa"]] 我想将字符串放入仅包含大小写不同的字符串的集合(或列表)中,例如,在上面,它是两个集合的集合: [["ABC", "abc", "AbC"], ["bca", "BCa"]]

So help me please to write collector for this problem. 所以请帮我写这个问题的收集器。

List<Set<String>> result = strs.stream()
                .collect(/* some collectors magic here */)

The "some collectors magic" you are looking for can be done in two steps: 您正在寻找的“一些收藏家魔术”可以通过两个步骤完成:

  • first, you need to group the elements by the property you are looking for. 首先,您需要按要查找的属性对元素进行分组。 In this case since you want to ignore the casing, String#toLowerCase does the job (don't forget the overloaded method that takes a Locale as parameter). 在这种情况下,由于您要忽略大小写,因此String#toLowerCase完成此工作(不要忘记以Locale作为参数的重载方法)。 You also want the values grouped to be unique so you can use the overloaded version of groupingBy to put them into a Set (the default implementation uses a List ) 您还希望分组的值唯一,以便可以使用groupingBy的重载版本将它们放入Set (默认实现使用List )。
  • since you're not interested in the keys, just grab the values from the resulting map and put them in a list (if you really need a list) using the collectingAndThen collector. 由于您对键不感兴趣,因此只需使用collectingAndThen器从生成的映射中获取值并将它们放在列表中(如果您确实需要一个列表)。

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toSet;

...

List<Set<String>> result = 
    strs.stream()
        .collect(collectingAndThen(groupingBy(String::toLowerCase, toSet()), 
                                   m -> new ArrayList<>(m.values())));

Try: 尝试:

List<Set<String>> result = 
  strs.stream()
      .collect(groupingBy(String::toLowerCase, toSet())) // Map<String, Set<String>>
      .values()            // Collection<Set<String>>
      .stream()            // Stream<Set<String>> 
      .collect(toList());  // List<Set<String>>

Here is code by AbacusUtil 这是AbacusUtil的代码

List<String> strs = N.asList("ABC", "abc", "bca", "BCa", "AbC");
List<Set<String>> lists = Stream.of(strs).groupBy(N::toLowerCase, Collectors.toSet()).map(Entry::getValue).toList();

Declaration: I'm the developer of AbacusUtil. 声明:我是AbacusUtil的开发人员。

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

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