Comportamento de stream.skip com operação de terminal não ordenada

Eu já liesta eesta perguntas, mas ainda duvidam se o comportamento observado deStream.skip foi planejado pelos autores do JDK.

Vamos ter uma entrada simples dos números 1..20:

List<Integer> input = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());

Agora vamos criar um fluxo paralelo, combinar ounordered() comskip() de diferentes maneiras e colete o resultado:

System.out.println("skip-skip-unordered-toList: "
        + input.parallelStream().filter(x -> x > 0)
            .skip(1)
            .skip(1)
            .unordered()
            .collect(Collectors.toList()));
System.out.println("skip-unordered-skip-toList: "
        + input.parallelStream().filter(x -> x > 0)
            .skip(1)
            .unordered()
            .skip(1)
            .collect(Collectors.toList()));
System.out.println("unordered-skip-skip-toList: "
        + input.parallelStream().filter(x -> x > 0)
            .unordered()
            .skip(1)
            .skip(1)
            .collect(Collectors.toList()));

A etapa de filtragem basicamente não faz nada aqui, mas acrescenta mais dificuldade ao mecanismo de fluxo: agora ele não sabe o tamanho exato da saída, portanto, algumas otimizações são desativadas. Eu tenho os seguintes resultados:

skip-skip-unordered-toList: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
// absent values: 1, 2
skip-unordered-skip-toList: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20]
// absent values: 1, 15
unordered-skip-skip-toList: [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20]
// absent values: 7, 18

Os resultados são completamente bons, tudo funciona como esperado. No primeiro caso, pedi para pular os dois primeiros elementos e depois coletar para listar em nenhuma ordem específica. No segundo caso, pedi para pular o primeiro elemento, depois me tornar desordenado e pular mais um elemento (não me importo com qual deles). No terceiro caso, primeiro entrei no modo não ordenado e depois pulei dois elementos arbitrários.

Vamos pular um elemento e coletar para a coleção personalizada no modo não ordenado. Nossa coleção personalizada será umaHashSet:

System.out.println("skip-toCollection: "
        + input.parallelStream().filter(x -> x > 0)
        .skip(1)
        .unordered()
        .collect(Collectors.toCollection(HashSet::new)));

A saída é satisfatória:

skip-toCollection: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
// 1 is skipped

Então, em geral, espero que, desde que o fluxo seja ordenado,skip() pula os primeiros elementos, caso contrário, pula os arbitrários.

No entanto, vamos usar uma operação de terminal não ordenada equivalentecollect(Collectors.toSet()):

System.out.println("skip-toSet: "
        + input.parallelStream().filter(x -> x > 0)
            .skip(1)
            .unordered()
            .collect(Collectors.toSet()));

Agora a saída é:

skip-toSet: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20]
// 13 is skipped

O mesmo resultado pode ser alcançado com qualquer outra operação não ordenada do terminal (comoforEach, findAny, anyMatchetc.). Removendounordered() passo neste caso não muda nada. Parece que enquantounordered() Se o passo corretamente fizer com que o fluxo não seja ordenado a partir da operação atual, a operação do terminal não ordenado fará com que todo o fluxo seja desordenado desde o início, apesar de isso poder afetar o resultado seskip() foi usado. Isso me parece completamente enganador: espero que usar o coletor não ordenado seja o mesmo que transformar o fluxo no modo não ordenadopouco antes da operação do terminal e usando o coletor solicitado equivalente.

Então, minhas perguntas são:

Esse comportamento é intencional ou é um bug?Se sim, está documentado em algum lugar? Eu liStream.skip () documentação: não diz nada sobre operações não-ordenadas do terminal. Além dissoCaracterísticas.UNORDERED a documentação não é muito abrangente e não diz que a ordem será perdida para todo o fluxo. Finalmente,Encomenda A seção no resumo do pacote também não abrange este caso. Provavelmente estou perdendo alguma coisa?Se se pretende que uma operação terminal não ordenada torne todo o fluxo não ordenado, por queunordered() passo torna desordenado apenas desde este ponto? Posso confiar nesse comportamento? Ou tive sorte de meus primeiros testes funcionarem bem?

questionAnswers(2)

yourAnswerToTheQuestion