[英]Java 8 collector for Guava Immutable Table
使用案例:
通過返回類型為{R,C,V}
ImmutableTable
的方法的進程列表。 例如ImmutableTable of {Integer,String,Boolean} process(String item){...}
收集結果,即合並所有結果並返回ImmutableTable
。 有沒有辦法實現它?
目前的實施(波希米亞建議):
如何使用並行流? 以下代碼中是否存在並發問題? 使用Parallel流我在tableBuilder.build()上得到“索引1800處的NullPointerException”,但是在流中工作正常。
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(); }
雖然下面的代碼與流和並行流有關。 但是由於row和col的重復輸入,ImmutableBuild失敗了。 什么是在合並表時防止重復的最佳方法?
public 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); }
編輯:如果在合並不同的表時ImmutableTable.Builder中有任何重復的條目,那么它會失敗,
試圖通過將ImmutableTables放在HashBasedTable中來避免faluire
ImmutableTable.copyOf(itemListToProcess.parallelStream()
.map(itemString ->
ProcessorInstanceProvider.get()
.buildImmutableTable(itemString))
.collect(
Collector.of(
HashBasedTable::create,
HashBasedTable::putAll,
(a, b) -> {
a.putAll(b);
return a;
}));
)
但我得到運行時異常“引起:java.lang.IllegalAccessError:嘗試訪問類com.google.common.collect.AbstractTable”。
我們如何使用HashBasedTable作為Accumulator來收集ImmutablesTables,因為HashBasedTable用最新的條目覆蓋現有條目,如果我們嘗試放入重復條目並返回聚合的Immutable表,則不會失敗。
從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
}
這應該工作:
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));
您應該可以通過使用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));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.