Guava的ImmutableTable过滤通过Java 8并行流

时间:2016-09-01 07:30:40

标签: java java-8 guava java-stream collect

需要帮助通过并行流和收集器过滤Guava的ImmutableTable

不可变的tofilterTable;

Usecase:迭代toFilter并删除validEntry表中不存在或入口值为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有更好,更简洁的方法吗?

1 个答案:

答案 0 :(得分:0)

是的,你可以做得更好。您可以使用Table.Cell。这样,您可以将两个循环减少为一个循环。您甚至可以使用谓词使您的方法更通用。

我知道您写的是您的应用程序适用于Java 8,但是使用Java 8流和类似的酷东西根本不可能这样做因为Table实际上并不是为Java 8设计的,到目前为止(无法从Cell的Itera {ble,tor}构建表格;表格不需要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的一些魔力:

// 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);