用例:
处理字符串的方法列表,返回类型ImmutableTable
的{{1}}。例如{R,C,V}
收集结果,即合并所有结果并返回ImmutableTable of {Integer,String,Boolean} process(String item){...}
。有没有办法实现它?
目前的实施(如波希米亚人所建议):
如何使用并行流?以下代码中是否存在并发问题?使用并行流我在索引1800和#34;得到" NullPointerException;在tableBuilder.build()上,但与流工作正常。
ImmutableTable
虽然下面的代码与流和并行流有关。但是由于row和col的重复输入,ImmutableBuild失败了。什么是在合并表时防止重复的最佳方法?
ImmutableTable<Integer, String, Boolean> buildData() {
// list of 4 AwsS3KeyName
listToProcess.parallelStream()
//Create new instance via Guice dependency injection
.map(s3KeyName -> ProcessorInstanceProvider.get()
.fetchAndBuild(s3KeyName))
.forEach(tableBuilder::putAll);
return tableBuilder.build(); }
编辑: 如果在合并不同的表时ImmutableTable.Builder中存在任何重复条目,则它会失败,
通过将ImmutableTables放入HashBasedTable
来试图避免faluirepublic static <R, C, V> Collector<ImmutableTable<R, C, V>,
ImmutableTable.Builder<R, C, V>, ImmutableTable<R, C, V>>
toImmutableTable()
{
return Collector.of(ImmutableTable.Builder::new,
ImmutableTable.Builder::putAll, (builder1, builder2) ->
builder1.putAll(builder2.build()), ImmutableTable.Builder::build); }
但是我得到了运行时异常&#34;引起:java.lang.IllegalAccessError:试图访问com.google.common.collect.AbstractTable和#34;类。
我们如何使用HashBasedTable作为Accumulator来收集ImmutablesTables,因为HashBasedTable用最新的条目覆盖现有条目,如果我们尝试放入重复条目并返回聚合的Immutable表,则不会失败。
答案 0 :(得分:5)
自Guava 21以来,您可以使用ImmutableTable.toImmutableTable
收集器。
public ImmutableTable<Integer, String, Boolean> processList(List<String> strings) {
return strings.stream()
.map(this::processText)
.flatMap(table -> table.cellSet().stream())
.collect(ImmutableTable.toImmutableTable(
Table.Cell::getRowKey,
Table.Cell::getColumnKey,
Table.Cell::getValue,
(b1, b2) -> b1 && b2 // You can ommit merge function!
));
}
private ImmutableTable<Integer, String, Boolean> processText(String text) {
return ImmutableTable.of(); // Whatever
}
答案 1 :(得分:3)
这应该有效:
List<String> list; // given a list of String
ImmutableTable result = list.parallelStream()
.map(processor::process) // converts String to ImmutableTable
.collect(ImmutableTable.Builder::new, ImmutableTable.Builder::putAll,
(a, b) -> a.putAll(b.build())
.build();
这种减少是线程安全的。
或使用HashBasedTable
作为中间数据结构:
ImmutableTable result = ImmutableTable.copyOf(list.parallelStream()
.map(processor::process) // converts String to ImmutableTable
.collect(HashBasedTable::create, HashBasedTable::putAll, HashBasedTable::putAll));
答案 2 :(得分:3)
您应该可以使用Collector.of
静态工厂方法创建适当的Collector
来执行此操作:
ImmutableTable<R, C, V> table =
list.stream()
.map(processor::process)
.collect(
Collector.of(
() -> new ImmutableTable.Builder<R, C, V>(),
(builder, table1) -> builder.putAll(table1),
(builder1, builder2) ->
new ImmutableTable.Builder<R, C, V>()
.putAll(builder1.build())
.putAll(builder2.build()),
ImmutableTable.Builder::build));