Streams may or may not have a defined encounter order. Whether or not
a stream has an encounter order depends on the source and the
intermediate operations. Certain stream sources (such as List or
arrays) are intrinsically ordered,whereas others (such as HashSet)
are not.
If a stream is ordered,repeated execution of identical
stream pipelines on an identical source will produce an identical
result; if it is not ordered,repeated execution might produce
different results.
试图通过此代码了解上述行为
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的提取文本.
解决方法
目前,在java-8下,一旦你将元素放入一个HashSet(并且不改变它),就会有一个如何布局元素的顺序;但同样,在你不添加或删除任何一个的情况下.这可以随时改变,所以不要依赖它.
例如运行这个:
String[] colors = new String[] { "red","orange" }; List<String> colorsList = Arrays.asList(colors); HashSet<String> coloRSSet = new HashSet<>(); coloRSSet.addAll(colorsList); System.out.println(coloRSSet);
无论在java-8下多少次,你总会获得相同的输出:
[red,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,orange]
您可以看到输出更改,因为集合没有订单.
要点是没有顺序,事实上你确实看到订单不是每次都发生的保证 – 在java-8中可能会有一个破坏这个顺序的构建.事实上,例如java-9很容易观察到 – 其中有新的集合的随机化模式.
如果多次运行,结果会有所不同:
Set<String> set = Set.of("red","orange"); System.out.println(set);
很明显,你从这样一个Set中流,订单将无法保证,因此你确实会看到不同的运行结果.