对于返回Collectors.groupingBy()
的{{1}},是否暗示Map<K,List<T>>
是为了评估流?
我没有看到列表排序的明确描述,而并发版本明确表示没有排序。如果它没有以某种方式订购,我会期望它是一个收藏品,除了订单收到之外,我不会看到它可能会有什么其他订单。
我希望保证每个列表中的最后一个值是该组收到的最后一个值。
答案 0 :(得分:20)
groupingBy()
的文档说:
实施要求:
这会产生类似于:
的结果groupingBy(classifier, toList());
toList()
的文档说:
<强>返回:强>
Collector
以相遇顺序将所有输入元素收集到List
因此,要回答您的问题,只要您的信息流已定义encounter order,您就可以获得有序列表。
编辑:正如@Holger所指出的,groupingBy()
还必须尊重遭遇顺序以保留toList()
的排序约束。它在本说明中强烈暗示这一事实:
实施说明:
...如果不需要保留向下游收集器提供元素的顺序,则使用
groupingByConcurrent(Function, Collector)
可以提供更好的并行性能。
答案 1 :(得分:2)
不幸的是,这个保证没有明确说明。
但是,结果val conf = new SparkConf().setAppName("Writing string to File").setMaster("local")
val sc = new SparkContext(conf)
val stringRdd = sc.parallelize(Seq("Test String"))
stringRdd.saveAsTextFile("out\\string\\test")
目前没有Collector
特征,因此事实上,生成的UNORDERED
已被订购。
剩下的问题是,因为没有API合同不允许它,未来版本(或替代实现)是否可以添加该特性并生成无序列表?实际上,OpenJDK和Oracle都非常不愿意引入这些重大变化,即使它有充分的理由。
在这里,没有理由做出这样的改变;我认为依靠这种行为是安全的。
答案 2 :(得分:0)
我做了一个真实的测试,我以此顺序初始化了一个ArrayList<TimeBased>
:
{"1", "2019-03-22 10:20:03", "1"},
{"2", "2019-03-22 10:30:03", "2"},
{"2", "2019-03-22 11:20:03", "3"},
{"1", "2019-03-22 11:20:15", "4"},
{"3", "2019-03-22 11:35:03", "5"},
{"2", "2019-03-22 12:20:03", "6"}
并按第一列和第二列进行分组,但结果是:
id birth number
1 Fri Mar 22 10:20:03 CST 2019 1
1 Fri Mar 22 11:20:15 CST 2019 4
2 Fri Mar 22 12:20:03 CST 2019 6
2 Fri Mar 22 11:20:03 CST 2019 3
2 Fri Mar 22 10:30:03 CST 2019 2
3 Fri Mar 22 11:35:03 CST 2019 5
因此,您看到的顺序是意外的(日期列顺序混乱)。
然后我执行此操作(添加LinkedList :: new):
Map<Integer, Map<Date, List<TimeBased>>> grouped =
timeBasedBeans.stream().collect(groupingBy(TimeBased::getId, groupingBy(TimeBased::getPeriod,
LinkedHashMap::new, toList())));
然后顺序正确:
id birth number
1 Fri Mar 22 10:20:03 CST 2019 1
1 Fri Mar 22 11:20:15 CST 2019 4
2 Fri Mar 22 10:30:03 CST 2019 2
2 Fri Mar 22 11:20:03 CST 2019 3
2 Fri Mar 22 12:20:03 CST 2019 6
3 Fri Mar 22 11:35:03 CST 2019 5