1

我有以下课程

class A implements Comparable<A> {

    private String name;

    public A(String name) {
        this.name = name;
    }

    public String getName() {
       return name;
    }

    @Override
    public int compareTo(A o) {
        return o.getName().compareTo(this.name);
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        A a = (A) o;
        return name.equals(a.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

现在我的理解是,下面的代码应该产生一些类名或 null 但不是 IllegalStateException,如 java 文档中所述

如果此 Spliterator 的源由 Comparator 排序,则返回该 Comparator。如果源按自然顺序排序,则返回 null。否则,如果源未排序,则抛出 IllegalStateException。

List<A> arrayList = new ArrayList<>();
arrayList.add(new A("Y"));
arrayList.add(new A("G"));
arrayList.add(new A("J"));
arrayList.add(new A("A"));
arrayList.add(new A("Z"));

arrayList.sort(A::compareTo);
Comparator<? super A> comparator = arrayList.spliterator().getComparator();
System.out.println(comparator);

编辑 2

我相信我无法让您了解我在寻找什么。以此为例:

SortedSet<String> set = new TreeSet<>( Collections.reverseOrder() );
set.add("A");
set.add("D");
set.add("C");
set.add("B");
System.out.println(set);
System.out.println(set.spliterator().getComparator());

这输出为

[D, C, B, A]
java.util.Collections$ReverseComparator@7852e922

现在 Collections.reverseOrder() 只是 Comparator 的一个实现

由于这产生了正确的答案,我对我的代码的期望也是它应该输出一个像上面这样的类名。

那么我做错了什么?

4

1 回答 1

3

虽然 a 的特征Spliterator可能反映集合的当前内容,但它们通常仅取决于源集合的类型。因此,所有标准List实现从不报告SORTED特征,即使它们的元素恰好当前已排序,而所有SortedSet实现总是报告SORTED特征。

您可能很少需要自己使用此方法。数据处理 API 和StreamAPI 一样可以使用幕后特性来优化执行。例如,当检测到数据已经排序时,可能会跳过sorteda 的操作。Stream但是举一个不太明显的例子,distinct当数据按元素类型的自然顺序排序时可能会有所不同。

此外,流管道的状态可以作为一个例子,其中特性不是由类型决定的:

public static void main(String[] args) {
    check(Stream.of("foo", "bar").filter(x -> true));
    check(Stream.of("foo", "bar").sorted().filter(x -> true));
}
private static void check(Stream<?> s) {
    System.out.println("Type: "+s.getClass());
    System.out.println("sorted: "+s.spliterator().hasCharacteristics(Spliterator.SORTED));
    System.out.println();
}
Type: class java.util.stream.ReferencePipeline$2
sorted: false

Type: class java.util.stream.ReferencePipeline$2
sorted: true

通常,您不会使用此 API 来获取您自己创建的集合的比较器,因为您已经知道比较器。但是在某些情况下,拆分器的比较器不是源自您的代码(直接):

TreeMap<String, Integer> map = new TreeMap<>(Comparator.comparingInt(String::length));

Spliterator<Map.Entry<String, Integer>> sp = map.entrySet().spliterator();
if(sp.hasCharacteristics(Spliterator.SORTED)) {
    Comparator<? super Map.Entry<String, Integer>> comparator = sp.getComparator();
    System.out.println("Entry comparator: " + comparator);
    Map.Entry<String, Integer> e1 = new AbstractMap.SimpleEntry<>("some", 5);
    Map.Entry<String, Integer> e2 = new AbstractMap.SimpleEntry<>("string", 3);
    System.out.println(BinaryOperator.maxBy(comparator).apply(e1, e2));
}
于 2020-04-06T15:37:44.170 回答