特性の実際の意味を最初に見つけようとしたときに、Java 8の実装段階でその意味が明確に解決されていないと感じていて、そのために一貫して使用されていなかったことを認めなければなりません理由。
がSpliterator.IMMUTABLE
検討:
元素源が構造的に修飾することができないことを意味
特性値。つまり、要素を追加、置換、または削除できないため、このような変更はトラバーサル中には発生しません。
それはList
配列かといえば、その結果、配列を受け入れストリームとspliterator工場(そのクローン化されていない)レポート際、通常は構造的な変更とはみなされていない、このリストに「置き換え」を参照して奇妙ですIMMUTABLE
、LongStream.of(…)
またはArrays.spliterator(long[])
などです。
我々はもっと寛大に「クライアントによる限り観察できない」としてこれを解釈する場合は、CONCURRENT
に有意な差は一部の要素がかどうかを認識するためにどのような方法なしでクライアントに報告されるいずれかの場合のように、存在しません彼らは巡回中に追加されたか、または除去のために報告されなかったものがあるかどうかは、スプライテータを巻き戻して比較する方法がないためです。
仕様は継続:トラバーサル中に検出構造干渉に関する(ConcurrentModificationException
を投げるなど)文書のポリシーを有することが期待されるIMMUTABLE
又はCONCURRENT
報告しない
A Spliteratorを。
そして、それだけで、関連するもの、のいずれかの報告spliterator、IMMUTABLE
またはCONCURRENT
だ、ConcurrentModificationException
を投げたことがないことが保証されます。もちろん、CONCURRENT
は意味的にSIZED
を排除しますが、それはクライアントコードには影響しません。
実際、これらの特性はStream API内で使用されていないため、一貫性のない使用は決してどこかに気づかれません。
これもすべての中間操作がCONCURRENT
、IMMUTABLE
とNONNULL
特性をクリアする効果を持っている理由の説明です:ストリームの実装では、それらを維持していない彼らとストリームの状態を表す、内部クラスを使用していません。特定のストリームのためのそれの不在は効果がありませんので、
同様に、NONNULL
は、どこでも使用されていません。返さspliteratorは常に特性SIZED
とSUBSIZED
を報告
:私は
Spliterators.spliterator(long[] array, int fromIndex, int toIndex, int additionalCharacteristics)
に委譲Arrays.spliterator(long[], int, int)
の内部使用までLongStream.of(…)
問題を追跡することができます。発呼者は、スプライテータが報告する追加の特性を提供することができる。 (たとえば、配列がそれ以上変更されないことがわかっている場合はIMMUTABLE
と指定し、配列データに出会いの順序があると見なされる場合はORDERED
を指定します)。代わりに、SIZED
、SUBSIZED
、IMMUTABLE
、およびORDERED
を報告するスプライテータを返す、Arrays.spliterator(long[], int, int)
メソッドを代わりに使用することができます。
IMMUTABLE
の特性が一貫していないことに注意してください。 Arrays.spliterator
とArrays.stream
とLongStream.of(…)
は、指定してもという特性を報告しますが、発信者が変更を加えないように保証することはできません。アレイ。配列を構造的に変更することはできないため、要素を構造的な変更ではなく、別の意味を持たないようにすることを考慮しない限り、もう一度無意味になります。
そして明らかに、NONNULL
の特性が指定されていません。プリミティブ値はnull
ではなく、Spliterator.Abstract<Primitive>Spliterator
クラスは必ずNONNULL
という特性を注入しますが、Spliterators.spliterator(long[],int,int,int)
が返すスプライテータはSpliterator.AbstractLongSpliterator
から継承しません。
悪いことは、仕様を変更せずに修正できないということですが、良いことはとにかく結果がないことです。
我々は何の影響を持っていないCONCURRENT
、IMMUTABLE
、またはNONNULL
を持つすべての問題を、無視するのであれば、我々は
SIZED
とskip
& limit
を持っています。これはよく知られた問題です。skip
とlimit
がStream APIによって実装されています。他の実装も想像できる。これは、予測可能なサイズを持つ必要がありますが、現行の実装を前提とした無限ストリームとlimit
の組み合わせにも当てはまります。
Stream.concat(…)
とStream.empty()
との組み合わせ。空のストリームがではないことが妥当と思われます。は結果の順序に制約を課します。しかし、Stream.concat(…)
の1つの入力だけが順序を持たないときに順序を解放するという振る舞いは疑わしい。順序に関してあまりにも積極的であることは新しいことではないことに注意してください。this Q&Aは、意図的に最初に考えられた動作について説明していますが、Java 8のアップデート60以降で修正されています。おそらく、Stream.concat
は、 ...
.boxed()
の動作は説明が簡単です。 .mapToObj(Long::valueOf)
のように純粋に実装されている場合、結果はまだソートされているか別個であると仮定することができないので、すべての知識が失われます。しかし、これはJava 9で修正されました。そこで、LongStream.range(0,10).boxed()
はSUBSIZED|SIZED|ORDERED|SORTED|DISTINCT
の特性を持ち、実装に関連するすべての特性を維持します。
誰かが「あまりにも広すぎる」という質問を締めくくることに投票しました。私は1つで6つの質問のように見えるので、同じことをするように誘惑されました。一方、これらの詳細すべてについて全体的な説明がある可能性があります... – Nicolai
@Nicolai私は最初に投票しました...しかし、それは閉鎖するのはあまりにも良いので、私はそれを再調査しました。私はこのような良い質問のために、このオールインワンが好きです。いくつかのOracleユーザー(Stuart?またはBrian?)のほかに、私はHolgerがこれらの正確な組み込み関数を知ることを期待しています。熱心に待っています。 :) – Eugene
* '.mapToObj()はNONNULL、IMMUTABLE、DISTI [N] CT *を失うことがあることを理解しています。なぜソートされないのですか? – shmosel