Guava 的 ImmutableTable 通过 Java 8 并行流过滤
Guava's ImmutableTable filtering via Java 8 parallel stream
在通过并行流和收集器过滤 Guava 的 ImmutableTable 时需要帮助
Immutable tofilterTable;
Usecase:遍历 toFilter 并删除不存在的元素或 validEntry table 中的条目值为 false 的元素。
通过 for 循环的传统方式:
ImmutableTable<MarketplaceArc, String, ObjectB> filterInactive(final ImmutableTable<MarketplaceArc, String, ObjectB> toFilter) {
final ImmutableTable.Builder filteredResultBuilder =
ImmutableTable.builder();
final Map<MarketplaceArc, Map<String, ObjectB>> rowMap =
browseMappings.rowMap();
for (final Map.Entry<MarketplaceArc, Map<String, ObjectB>>
rowMapEntry : rowMap.entrySet()) {
for (final Map.Entry<String, ObjectB> entry :
rowMapEntry.getValue().entrySet()) {
if(ifActive(rowMap.getKey, entry)){
filteredResultBuilder.put(
rowMapEntry.getKey(),
entry.getKey(),
buildObjectB(entry));
}
}
}
return filteredResultBuilder.build();
}
有没有更好更简洁的方法通过 Java parallelStreams 做到这一点?
是的,你可以做得更好。您可以使用 Table.Cell
作为其中之一。这样,您就可以将两个循环缩减为一个。您甚至可以使用谓词使您的方法更通用。
我知道您写过您的应用程序适用于 Java 8,但是使用 Java 8 流和类似的很酷的东西根本不可能这样做,因为 Table
到目前为止,对于 Java 8 的设计还不是很好(无法从 Cell
s 的 Itera{ble,tor} 构建 table;tables 不不需要 BiPredicate
但 TriPredicate
)。因此,让我们改进您的代码,简单明了。
普通旧循环,针对 Table
s
进行了优化
这是基本版本。没有什么特别的,但是比你的方式做得更好,因为它不依赖于中间复杂的数据结构(你一直在使用地图,例如,这个解决方案没有)。
ImmutableTable<MarketplaceArc, String, ObjectB> filterInactive(Table<MarketplaceArc, String, ObjectB> unfiltered) {
ImmutableTable.Builder<MarketplaceArc, String, ObjectB> filtered = ImmutableTable.builder();
for (Table.Cell<MarketplaceArc, String, ObjectB> cell: unfiltered.cells()) {
if (isActive(cell.getRow(), cell.getValue())) {
filtered.put(cell);
}
}
return filtered.build();
}
带谓词的通用解决方案
更通用的解决方案是使用通用过滤方法。这将使您的代码更具可读性,感谢一些 Java 8 magic:
// Generic method.
<R,C,V> ImmutableTable<R,C,V> filterToImmutable(Table<R,C,V> unfiltered, Predicate<Table.Cell<R,C,V>> predicate) {
ImmutableTable.Builder<R,C,V> filtered = ImmutableTable.builder();
// Actually, let's use some Java 8, just because we can!
unfiltered.cells().parallelStream()
.filter(predicate)
.foreach(filtered::put);
return filtered.build();
}
// Specific predicate
boolean isActiveCell(Table.Cell<MarketplaceArc, String, ObjectB> cell) {
return isActive(cell.getRow(), cell.getValue());
}
// Use all you've written, with some Java 8, just because we can. Again.
ImmutableTable<MarketplaceArc, Map<String, ObjectB> unfiltered = ... ;
ImmutableTable<MarketplaceArc, Map<String, ObjectB> filtered = filterToImmutable(unfiltered, this::isActiveCell);
在通过并行流和收集器过滤 Guava 的 ImmutableTable 时需要帮助
Immutable tofilterTable;
Usecase:遍历 toFilter 并删除不存在的元素或 validEntry table 中的条目值为 false 的元素。 通过 for 循环的传统方式:
ImmutableTable<MarketplaceArc, String, ObjectB> filterInactive(final ImmutableTable<MarketplaceArc, String, ObjectB> toFilter) {
final ImmutableTable.Builder filteredResultBuilder =
ImmutableTable.builder();
final Map<MarketplaceArc, Map<String, ObjectB>> rowMap =
browseMappings.rowMap();
for (final Map.Entry<MarketplaceArc, Map<String, ObjectB>>
rowMapEntry : rowMap.entrySet()) {
for (final Map.Entry<String, ObjectB> entry :
rowMapEntry.getValue().entrySet()) {
if(ifActive(rowMap.getKey, entry)){
filteredResultBuilder.put(
rowMapEntry.getKey(),
entry.getKey(),
buildObjectB(entry));
}
}
}
return filteredResultBuilder.build();
}
有没有更好更简洁的方法通过 Java parallelStreams 做到这一点?
是的,你可以做得更好。您可以使用 Table.Cell
作为其中之一。这样,您就可以将两个循环缩减为一个。您甚至可以使用谓词使您的方法更通用。
我知道您写过您的应用程序适用于 Java 8,但是使用 Java 8 流和类似的很酷的东西根本不可能这样做,因为 Table
到目前为止,对于 Java 8 的设计还不是很好(无法从 Cell
s 的 Itera{ble,tor} 构建 table;tables 不不需要 BiPredicate
但 TriPredicate
)。因此,让我们改进您的代码,简单明了。
普通旧循环,针对 Table
s
这是基本版本。没有什么特别的,但是比你的方式做得更好,因为它不依赖于中间复杂的数据结构(你一直在使用地图,例如,这个解决方案没有)。
ImmutableTable<MarketplaceArc, String, ObjectB> filterInactive(Table<MarketplaceArc, String, ObjectB> unfiltered) {
ImmutableTable.Builder<MarketplaceArc, String, ObjectB> filtered = ImmutableTable.builder();
for (Table.Cell<MarketplaceArc, String, ObjectB> cell: unfiltered.cells()) {
if (isActive(cell.getRow(), cell.getValue())) {
filtered.put(cell);
}
}
return filtered.build();
}
带谓词的通用解决方案
更通用的解决方案是使用通用过滤方法。这将使您的代码更具可读性,感谢一些 Java 8 magic:
// Generic method.
<R,C,V> ImmutableTable<R,C,V> filterToImmutable(Table<R,C,V> unfiltered, Predicate<Table.Cell<R,C,V>> predicate) {
ImmutableTable.Builder<R,C,V> filtered = ImmutableTable.builder();
// Actually, let's use some Java 8, just because we can!
unfiltered.cells().parallelStream()
.filter(predicate)
.foreach(filtered::put);
return filtered.build();
}
// Specific predicate
boolean isActiveCell(Table.Cell<MarketplaceArc, String, ObjectB> cell) {
return isActive(cell.getRow(), cell.getValue());
}
// Use all you've written, with some Java 8, just because we can. Again.
ImmutableTable<MarketplaceArc, Map<String, ObjectB> unfiltered = ... ;
ImmutableTable<MarketplaceArc, Map<String, ObjectB> filtered = filterToImmutable(unfiltered, this::isActiveCell);