因此,我尝试使用reduce
a List<String>
并创建一个Map<String,List<Integer>>
map的键,它是原始键的成员List
,而值是List
该键发生的索引的a 。通常,对于大多数其他语言,使用reduce,inject,fold等,这是一个非常简单的操作。例如,在Javascript中,您可以执行以下操作:
let mappings = someStrings.reduce( function( mappings, val, index ) {
if( !mappings[val] ) {
mappings[ val ] = [];
}
mappings[ val ].push( index );
return mappings;
}, {});
但是,我发现在Java中进行还原是相当复杂的,因为Java认为应该编写功能操作,以便可以“透明地”并行化这些功能操作,但是这样的简单情况却增加了额外的开销。在Java中,我不得不编写一些痛苦的东西:
List<String> headers = ...
Map<String,List<Integer>> mappings = IntStream.range(0, headers.size())
.map( i -> new Pair<String,Integer>( headers.get(i), i ) )
.reduce( new HashMap<>(), ( mapping, pair ) -> {
if( !mappings.contains( pair.getFirst() ) ) {
mappings.put( pair.getFirst(), new ArrayList<String>() );
}
mappings.get( pair.getFirst() ).add( pair.getSecond() );
return mappings;
}, ( x, y ) -> x );
如果我被迫实际合并x和y,那么在合并复杂对象的情况下,对于简单的单线程情况,它将变得非常复杂。这确实显示了Java做出的设计决策所带来的复杂性。
我的问题是我是否缺少有关减少的内容?有没有一种方法可以将并行设计简化为双线程设计,使之更简单(我只是看不到)?并行的选项很好,但是大多数时候我对简单的单线程reduce感到满意。
您的操作看起来很复杂,原因有两个。首先,您正在执行不必要的中间操作映射到对类型。其次,您使用了错误的工具来完成工作。代替减少,您需要Mutable Reduction。
完整的操作可以写成
Map<String,List<Integer>> mappings = IntStream.range(0, headers.size()).boxed()
.collect(Collectors.groupingBy(headers::get));
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句