public static void main(String[] args) throws IOException
{
    HashSet set = new HashSet<String>();
    set.add("{}");
    set.add("{a}");
    set.add("{b}");
    set.add("{a, b}");
    set.add("{a, c}");
    sortedSet(set);
}
public static void sortedSet(HashSet set)
{
    List<String> setList = new ArrayList<String>(set);
    List<String> orderedByAlpha = new ArrayList<String>(set);
    //sort by alphabetical order
    orderedByAlpha = (List<String>) setList.stream()
        .sorted((s1, s2) -> s1.compareToIgnoreCase(s2))
        .collect(Collectors.toList());
    System.out.println(orderedByAlpha);
}我尝试按字母顺序排序,但得到的输出如下:
[{a, b}, {a, c}, {a}, {b}, {}]但它应该是:
[{a}, {a, b}, {a, c}, {b}, {}]发布于 2018-11-21 23:14:36
嗯,正如@Aomine和@Holger已经提到的,你需要一个自定义的比较器。
但是我觉得他们的解决方案看起来是过度设计的。您不需要任何代价高昂的操作,如split和substring
String.substring会创建一个新的String对象并在幕后调用System.arraycopy(),而String.split的开销会更大。它遍历您的字符串并多次调用String.substring。此外,它还创建了一个ArrayList来存储所有子字符串。如果子字符串的数量足够大,那么您的ArrayList将需要扩展其容量(可能不止一次),从而导致另一次System.arraycopy().调用
对于您的简单情况,我会稍微修改一下内置String.compareTo方法的代码:
Comparator<String> customComparator =
            (s1, s2) -> {
                int len1 = s1.length();
                int len2 = s2.length();
                if (len1 == 2) return 1;
                if (len2 == 2) return -1;
                int lim = Math.min(len1, len2) - 1;
                for (int k = 1; k < lim; k++) {
                    char c1 = s1.charAt(k);
                    char c2 = s2.charAt(k);
                    if (c1 != c2) {
                        return c1 - c2;
                    }
                }
                return len1 - len2;
            };它将比较复杂度为O(n)的字符串,其中n是较短字符串的长度。同时,它既不会创建任何新对象,也不会执行任何阵列复制。
可以使用Stream API实现相同的比较器
Comparator<String> customComparatorUsingStreams =
            (s1, s2) -> {
                if (s1.length() == 2) return 1;
                if (s2.length() == 2) return -1;
                return IntStream.range(1, Math.min(s1.length(), s2.length()) - 1)
                        .map(i -> s1.charAt(i) - s2.charAt(i))
                        .filter(i -> i != 0)
                        .findFirst()
                        .orElse(0);
            };您可以像这样使用您的自定义比较器:
List<String> orderedByAlpha = setList.stream()
                                     .sorted(customComparatorUsingStreams)
                                     .collect(Collectors.toList());
System.out.println(orderedByAlpha);https://stackoverflow.com/questions/53366258
复制相似问题