Reputation: 71
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, i.e. for example above it would be collection of two sets: [["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 */)
Upvotes: 5
Views: 6055
Reputation: 1284
Here is code by abacus-common
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 abacus-common.
Upvotes: 0
Reputation: 93892
The "some collectors magic" you are looking for can be done in two steps:
String#toLowerCase
does the job (don't forget the overloaded method that takes a Locale
as parameter). 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
)collectingAndThen
collector.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())));
Upvotes: 11
Reputation: 53859
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>>
Upvotes: 2