16

在 Java 8 中,提供了各种方便的实用程序来从数组构建高效的 Spliterators。但是,没有提供工厂方法来构建带有比较器的 Spliterator。显然 Spliterators 允许附加比较器;他们有一个getComparator()方法和一个SORTED属性。

图书馆作者应该如何构建SORTEDSpliterators?

4

2 回答 2

7

似乎没有预见到会有这样一个Spliterator非自然的顺序。但实施起来并不难。它可能看起来像这样:

class MyArraySpliterator implements Spliterator.OfInt {
    final int[] intArray;
    int pos;
    final int end;
    final Comparator<? super Integer> comp;

    MyArraySpliterator(int[] array, Comparator<? super Integer> c) {
        this(array, 0, array.length, c);
    }
    MyArraySpliterator(int[] array, int s, int e, Comparator<? super Integer> c) {
        intArray=array;
        pos=s;
        end=e;
        comp=c;
    }
    @Override
    public OfInt trySplit() {
        if(end-pos<64) return null;
        int mid=(pos+end)>>>1;
        return new MyArraySpliterator(intArray, pos, pos=mid, comp);
    }
    @Override
    public boolean tryAdvance(IntConsumer action) {
        Objects.requireNonNull(action);
        if(pos<end) {
            action.accept(intArray[pos++]);
            return true;
        }
        return false;
    }
    @Override
    public boolean tryAdvance(Consumer<? super Integer> action) {
        Objects.requireNonNull(action);
        if(pos<end) {
            action.accept(intArray[pos++]);
            return true;
        }
        return false;
    }
    @Override
    public long estimateSize() {
        return end-pos;
    }
    @Override
    public int characteristics() {
        return SIZED|SUBSIZED|SORTED|ORDERED|NONNULL;
    }
    @Override
    public Comparator<? super Integer> getComparator() {
        return comp;
    }
}

但是 Java 8 还没有完全修复。也许决赛中会有JRE提供的解决方案。

于 2013-11-21T14:07:12.127 回答
3

您可以创建一个 ORDERED Spliterator:

  • 通过具有适当的 Collection 开始iterator()

    如果对应的 Collection.iterator() 记录了订单,则 Collection 具有遇到订单。如果是这样,遭遇顺序与记录的顺序相同。否则,集合没有遇到顺序。

    通常,TreeSet.spliterator#getComparator返回 TreeSet 的 Comparator,但ArrayList.spliterator#getComparator返回 null:顺序是递增索引。

  • 或者,如果您有一个数组,则可以使用Arrays辅助类中提供的新便利方法,例如Arrays.spliterator(double[])

    拆分器报告 Spliterator.SIZED、Spliterator.SUBSIZED、Spliterator.ORDERED 和 Spliterator.IMMUTABLE。

  • 或(这就是这样Arrays.spliterator做的)通过显式提供特征,例如:Spliterators.spliterator(array, Spliterator.ORDERED);

当集合与特定的比较器(或数组)无关时,在“拆分”之前进行排序是有意义的。

于 2013-11-19T17:19:25.740 回答