16

Java 8 では、配列から効率的なスプリッテレータを構築するために、さまざまな便利なユーティリティが提供されています。ただし、コンパレータを使用して Spliterator を構築するためのファクトリ メソッドは提供されていません。明らかに、スプリッテレータにはコンパレータを接続できます。getComparator()メソッドとSORTEDプロパティがあります。

ライブラリの作成者はSORTEDスプリッテレータをどのように構築することになっていますか?

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() が順序を文書化する場合、コレクションには遭遇順序があります。その場合、遭遇順序は文書化された順序と同じです。それ以外の場合、コレクションには遭遇順序がありません。

    通常、TreeSet.spliterator#getComparatorTreeSet の 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 に答える