受这个问题的启发,我开始研究有序流与无序流、并行流与顺序流以及终端操作,它们考虑的是相遇顺序,而终端操作则不考虑相遇顺序。
在链接问题的一个答案中,显示了一个类似于此的代码:
List<Integer> ordered = Arrays.asList(
1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4);
List<Integer> result = new CopyOnWriteArrayList<>();
ordered.parallelStream().forEach(result::add);
System.out.println(ordered);
System.out.println(result);
名单确实不同。无序
列表甚至从一次运行更改到另一次运行,表明结果实际上是不确定的。
因此,我创建了另一个示例:
CopyOnWriteArrayList<Integer> result2 = ordered.parallelStream()
.unordered()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
System.out.println(ordered);
System.out.println(result2);
我希望看到类似的结果,因为流既并行又无序(可能unordered()
是冗余的,因为它已经并行了)。但是,结果列表是有序的,即它等于源列表。
所以我的问题是为什么要订购收集的列表?收集是否总是尊重相遇顺序,即使是并行的、无序的流?是特定的Collectors.to集合(...)
收集器强制遭遇顺序?
留档流#收藏已经提到:
当并行执行时,可以实例化、填充和合并多个中间结果,以保持可变数据结构的隔离。因此,即使在与非线程安全的数据结构(如ArrayList)并行执行时,并行缩减也不需要额外的同步。
这意味着流#collect
做两件主要的事情:split
但是我在jdk-8中有一个特殊的例子,你可以获取不同的结果:)。当创建一个无序的流流由流#生成,然后你可以在收藏家#toList
上获取不同的结果,例如:
Set<Set<Integer>> result = IntStream.range(0, 10).mapToObj(__ -> {
return unordered().parallel().collect(toSet());
}).collect(toSet());
assert result.each.size() == 100000; // ok
// v--- surprised, it was pass
assert result.size() > 1;
Stream<Integer> unordered() {
AtomicInteger counter = new AtomicInteger();
return Stream.generate(counter::getAndIncrement).limit(10000);
}
在当前的实现中,我检查了java-8和java-9,对于非并发收集器(Collector.Characteristics.unordered
),在collect
阶段忽略无序标志。实现是允许这样做的,这在某种程度上是一个类似的问题。
在您链接的同一个问题中,我提供了一个示例,说明了findFirst
实际上是如何从jdk-8更改为jdk-9的。
收集器。toCollection
返回一个收集器
,该收集器缺少收集器。特点。无序
特征。指定收集器的另一个收集器。特点。无序的
可能表现不同。
也就是说:“无序”意味着没有保证,不保证变化。如果库发现最容易将无序的集合按顺序处理,则允许它这样做,并且允许该行为在星期二或满月时一个版本一个版本地更改。
(还请注意,如果要使用并行流,Collectors.to集合
不需要使用并发集合实现;toCollection(ArrayList::new)
可以正常工作。这是因为收集器没有收集器。特点。(CONCURRENT
特性,因此它使用了一种即使在并行流中也适用于非并发集合的集合策略。)(
如果您使用的是无序流,但收集器不是无序的
,反之亦然,我怀疑您是否能从框架中得到任何保证。如果有一张桌子,它会说“给你。”
对于流。collect
,我认为当前的实施有三种策略可供选择:
本页包含内容: 用以输入/输出的参数指针 作为数组使用的参数指针 用作字符串参数的指针 指针参数转换的安全性 Objective-C和C的API常常会需要用到指针。Swift中的数据类型都原生支持基于指针的Cocoa API,不仅如此,Swift会自动处理部分最常用的将指针作为参数传递的情况。这篇文章中,我们将着眼于在Swift中让C语言指针与变量、数组和字符串共同工作。 用以输入/输出的参数指针
问题内容: 让我们简单地输入数字1..20: 现在,让我们创建一个并行流,结合以不同的方式和收集的结果: 过滤步骤在这里基本上不执行任何操作,但是给流引擎增加了更多难度:现在它不知道输出的确切大小,因此一些优化被关闭了。我得到以下结果: 结果完全正确,一切正常。在第一种情况下,我要求跳过前两个元素,然后以没有特定的顺序收集到列表。在第二种情况下,我要求跳过第一个元素,然后变成无序并跳过另一个元素(
我有一个记录课程: 我创建了一个包含很多记录的大列表。只有第二个和第五个值,即i/10000和i,稍后分别由getter使用。 请注意,前10000条记录的类别2为0,接下来的10000条记录的类别1等,而值1按顺序为0-114999。 我创建了一个既并行又排序的流。 我有一个ForkJoinPool,它维护8个线程,这是我电脑上的内核数。 我使用这里描述的技巧将流处理任务提交给我自己的,而不是常
问题内容: 是否有办法将JavaScript字符串传递给MySQL的NodeJSfriendly?我正在尝试将电子邮件地址传递给我的NodeJS服务器并查询到MySQL数据库。在执行常规文本(例如用户名)时可以正常工作,但电子邮件地址却不能。显然,使用转义不是正确的答案,因为这并不意味着要进行SQL插入。我假设我需要一些PHP函数。 问题答案: 事实证明,mysql_real_escape_str
是否有任何保证在顺序和有序流上的操作是按遇到顺序处理的? 我是说,如果我有这样的代码: 是否可以保证它将按照生成范围的遇到顺序执行myFunction()调用? 我找到了Stream类的JavaDocs草案,它明确地说明了以下内容: 对于顺序流管道,如果管道源具有已定义的遇到顺序,则所有操作都按照管道源的遇到顺序执行。 但是它没有提到顺序流,这个例子是针对并行流的(我的理解是,顺序流和并行流都是正
问题内容: 我有一个MySQL数据库,其中存储了每个用户的数据。 我想为每个用户添加一个朋友列表。我应该为数据库中的每个用户创建一个朋友表还是有更好的方法? 问题答案: 假设所有朋友也都在用户表中,则需要一个朋友表,该表定义了简单的一对多关系-将用户表链接回自身。所以 其中UserIDLink1和UserIDLink2都是Users表上的外键。 例如,如果我有三个用户 并且Joe和Jane是朋友,