作者:牛牛发的 | 来源:互联网 | 2023-01-21 11:14
我读了这篇Java 8官方文档:
流可能有也可能没有已定义的遭遇顺序.流是否具有遭遇顺序取决于源和中间操作.某些流源(例如List或数组)本质上是有序的,而其他流(例如HashSet)则不是.
如果订购了流,则在相同的源上重复执行相同的流管道将产生相同的结果; 如果没有订购,重复执行可能会产生不同的结果.
试图通过此代码了解上述行为
public class StreamOrderValidator
{
public static void main( String[] args )
{
String[] colors=new String[] {"red","green","blue","orange"};
List colorsList=Arrays.asList(colors);
HashSet colorsSet=new HashSet<>();
colorsSet.addAll(colorsList);
System.out.println(colorsSet); // [red, orange, green, blue]
List processedColorsSet = processStream(colorsSet.stream());
System.out.println(processedColorsSet); // [RED, ORANGE, GREEN, BLUE]
}
private static List processStream(Stream colorStream) {
List processedColorsList = colorStream.filter(s->s.length()<=6).
map(String::toUpperCase).collect(Collectors.toList());
return processedColorsList;
}
}
我多次运行此代码,结果流中元素的顺序始终相同(显示为注释).我无法弄清楚这是如何证明以上引用的文字"订单不被保留为无序集合".
我肯定误解了javadocs提取的文本.
1> Eugene..:
确实存在一些误解.A HashSet
或任何Set
不是关于订单,除非TreeSet
是基于a订购的Comparator
.
目前,在java-8下,一旦你将元素放入一个HashSet
(并且不要改变它) - 将会有一个如何布置元素的顺序; 但同样,在你不添加或删除任何一个的情况下.这可以随时改变,所以不要依赖它.
比如运行这个:
String[] colors = new String[] { "red", "green", "blue", "orange" };
List colorsList = Arrays.asList(colors);
HashSet 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
s 存在随机化模式.
如果多次运行,结果会有所不同:
Set set = Set.of("red", "green", "blue", "orange");
System.out.println(set);
很明显,你stream
从这样Set
的订单中得不到保证,因此你确实会看到不同的运行结果.