Java 8 では、配列から効率的なスプリッテレータを構築するために、さまざまな便利なユーティリティが提供されています。ただし、コンパレータを使用して Spliterator を構築するためのファクトリ メソッドは提供されていません。明らかに、スプリッテレータにはコンパレータを接続できます。getComparator()
メソッドとSORTED
プロパティがあります。
ライブラリの作成者はSORTED
スプリッテレータをどのように構築することになっていますか?
Java 8 では、配列から効率的なスプリッテレータを構築するために、さまざまな便利なユーティリティが提供されています。ただし、コンパレータを使用して Spliterator を構築するためのファクトリ メソッドは提供されていません。明らかに、スプリッテレータにはコンパレータを接続できます。getComparator()
メソッドとSORTED
プロパティがあります。
ライブラリの作成者はSORTED
スプリッテレータをどのように構築することになっていますか?
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 が提供するソリューションが登場するかもしれません。
ORDERED Spliterator を作成できます。
Collectionから適切なiterator()
:
対応する Collection.iterator() が順序を文書化する場合、コレクションには遭遇順序があります。その場合、遭遇順序は文書化された順序と同じです。それ以外の場合、コレクションには遭遇順序がありません。
通常、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);
コレクションが特定のコンパレータ (または配列) に関連付けられていない場合は、「分割」する前にソートするのが理にかなっています。