問題

私はこのJava 8公式ドキュメントを読んでいます:

ストリームは定義された遭遇順序を持つかもしれません。 ストリームには遭遇順序があり、ソースと 中間操作。特定のストリームソース(List や 配列)は本質的に順序付けられていますが、他のもの(HashSetなど) そうではありません。
または ストリームが順序付けられている場合、同一の実行を繰り返します。 同一のソース上のパイプラインをストリームすると、同じものが生成されます 結果;順序付けられていない場合、繰り返し実行すると 結果が違う

このコードで上記の動作を理解しようとしました

 public class StreamOrderValidator
{
    public static void main( String[] args )
    {
        String[] colors=new String[] {"red","green","blue","orange"};
        List<String> colorsList=Arrays.asList(colors);

        HashSet<String> colorsSet=new HashSet<>();
        colorsSet.addAll(colorsList);
        System.out.println(colorsSet);            // [red, orange, green, blue]

        List<String> processedColorsSet = processStream(colorsSet.stream());
        System.out.println(processedColorsSet);   // [RED, ORANGE, GREEN, BLUE]
    }

    private static List<String> processStream(Stream<String> colorStream) {
        List<String> processedColorsList = colorStream.filter(s->s.length()<=6).
                map(String::toUpperCase).collect(Collectors.toList());
        return processedColorsList;
    }
}
 

私はこのコードを何度も実行し、結果として得られるストリームの要素の順序は常に同じでした(コメントとして表示されます)。私はこれが "順序付けられていないコレクションのために保存されていない注文"についての上記の引用されたテキストをどのように正当化するのか理解できません。

私は間違いなくjavadocsから抽出されたテキストを誤解しています。

  ベストアンサー

実際にここに少し誤解があります。 HashSetまたは任意のSetは、Comparatorに基づいて順序付けられたTreeSetでない限り、注文についてはありません。

現時点では、java-8の下で、要素をHashSetに入れると(変更しないでください)、要素の配置方法の順序があります。しかし、繰り返しますが、それらのいずれかを追加または削除しないという条件の下で。これはいつでも変更できるので、それに依存しないでください。

たとえば、次のように実行します。

  String[] colors = new String[] { "red", "green", "blue", "orange" };
 List<String> colorsList = Arrays.asList(colors);

 HashSet<String> colorsSet = new HashSet<>();
 colorsSet.addAll(colorsList);
 System.out.println(colorsSet);
 

現時点でjava-8の下で何回も同じ出力が得られます。

 [red, orange, green, blue]
 

しかし、一度内部の再シャッフルを行うと、

     for (int i = 0; i < 1000; ++i) {
        colorsSet.add("" + i);
    }

    for (int i = 0; i < 1000; ++i) {
        colorsSet.remove("" + i);
    }   


    System.out.println(colorsSet); // [blue, red, green, orange]
 

Set s には順序がないため、出力が変わることがわかります。 重要なポイントは、注文がないことです。注文が表示されるという事実は、毎回発生する保証ではありません。この順序を破るjava-8にビルドがあるかもしれません。実際には、java-9で簡単に観測できます。ここでは、新しいSetのランダム化パターンがあります。

これを複数回実行すると、結果は異なります。

  Set<String> set = Set.of("red", "green", "blue", "orange");
 System.out.println(set);
 

したがって、明らかにそのようなSetからのstreamの順序は保証されないため、実際には実行とは異なる結果が表示されます。

  同じタグがついた質問を見る

javajava-8java-streamhashset