[英]What is the computational complexity of generating a stream from a hashset in java? We may consider a hashset with $n$ elements and $m$ capacity
[英]Understanding order of elements in stream generated from HashSet
我读了这篇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
,订单将无法保证,因此你确实会看到不同的运行结果。
您所看到的基本上是运气,您正在流式传输的HashSet按顺序返回值。 如果随着时间的推移添加了足够的值,最终会看到来自流的不同结果,因为HashSet的底层HashMap必须调整自身并重新排序。
你提供的(四种颜色)偶然会每次返回相同的结果,因为底层的HashMap不需要调整自身大小并重新排序值。
请记住,根据Java API文档,HashSet由HashMap支持,这个问题及其接受的答案涵盖了您通过解释HashMap的行为而看到的内容:
重复执行可能会产生不同的结果
这might
就是这个词。 即使它不保证订单,也不意味着订单每次都是随机的。 元素基于hashcode
放置。 尝试一些不同的值:
String[] colors=new String[] {"5reegdfg","fsdfsd6546","fsdfxvc4","77ggg"};
List<String> colorsList=Arrays.asList(colors);
HashSet<String> intSet =new HashSet<>();
intSet.addAll(colorsList);
intSet.forEach(e -> System.out.print(e + " "));
System.out.println();
intSet.add("fvcxbxb78ok");
intSet.forEach(e -> System.out.print( e + " "));
输出是这样的:
fsdfxvc4 5reegdfg 77ggg fsdfsd6546
fsdfxvc4 fvcxbxb78ok 5reegdfg 77ggg fsdfsd6546
如您所见,此示例中的顺序不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.