简体   繁体   English

Java 8流分组通过使用比较器

[英]Java 8 streams groupingBy using a Comparator

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. 但是, groupingBy收集器要求将事物按字母分组。 I don't have a specific letter here, just a Comparator (the collator). 我在这里没有特定的字母,只有Comparator (整理器)。

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]]

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

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