Reputation: 6123
I'm interested in turning the following code into something more succinct:
final String[] strings = {"a", "B", "A", "á", "Á"};
final Collator collator = Collator.getInstance(Locale.FRANCE);
collator.setStrength(Collator.PRIMARY);
final Map<String, Set<String>> m = new TreeMap<>(collator);
for (String s : strings) {
m.compute(s, (k, v) -> {
if (v == null)
v = new TreeSet<String>();
v.add(s);
return v;
});
}
final Collection<Set<String>> requiredResult = m.values();
requiredResult.forEach(System.out::println);
Output:
[A, a, Á, á]
[B]
Basically what this does is consider letters as equal by ignoring case and diacritical marks and group such "equal" letters together. (By the way, I'm aware that most languages don't consider letters equal if the differ by diacritical mark; this is just a contrived example.)
I was thinking of shortening it by using streams. However, the groupingBy
collector requires things to be grouped by a letter. I don't have a specific letter here, just a Comparator
(the collator).
Upvotes: 2
Views: 3108
Reputation: 785
Maybe such way:
final String[] strings = {"a", "B", "A", "á", "Á"};
final Collator collator = Collator.getInstance(Locale.FRANCE);
collator.setStrength(Collator.PRIMARY);
Collection<Set<String>> result = Arrays.stream(strings)
.collect(Collectors.groupingBy(collator::getCollationKey, Collectors.toSet()))
.values();
System.out.println(result); //[[a, A, á, Á], [B]]
Upvotes: 5