繁体   English   中英

使用Java 8的更好方法

[英]Better way to doing with Java 8

我将以下代码转换为java 8代码。 我想知道我是否做得恰到好处还是有其他不错的方法。

Java 7

for (final Category category : categories) {
      final List<Category> subCategories = getCategories(category);
      if (subCategories != null) {
        currentLevel.addAll(subCategories);
      }
    }

Java8

categories.stream().map(category -> getCategories(category)).filter(list->list!=null).flatMap(cat -> cat.parallelStream()).collect(Collectors.toList())

任何java 8方式将下面的代码解析成紧凑的形式。

while (CollectionUtils.isNotEmpty(currentLevel)) {
  for (final Iterator<Category> iterator = currentLevel.iterator(); iterator.hasNext();) {
    final Category category = iterator.next();
    if (result == null) {
      result = new HashSet<Category>();
    }
    if (!result.add(category)) {
      // avoid cycles by removing all which are already found
      iterator.remove();
    }
  }

  if (currentLevel.isEmpty()) {
    break;
  }
  final Collection<Category> nextLevel = getAllSubcategories(currentLevel);
  currentLevel = nextLevel;
}

你的解决方案没问题,只是平行映射到并行流是没用的。 如果你看一下OpenJDK / OracleJDK中的flatMap实现,你会发现通过传递给flatMap lambda创建的流会立即变为顺序模式。 所以你不会有任何并行性,最好用stream()替换parallelStream() stream()以避免混淆。 如果您真的想要并行化工作,通常最好只并行化最外层的流。

也许是一个偏好问题,但你可以用方法引用替换那些lambdas:

categories.stream()
          .map(this::getCategories)
          .filter(Objects::nonNull)
          .flatMap(List::stream)
          .collect(Collectors.toList())

太糟糕了,列表显然可以为null (真的吗?)...否则你可以使用flatMap

我不会在另一个流操作中使用parallelStream

对于第二个问题,通常基于流的删除重复项的方法是将元素复制到不同的集合中,使用distinct()操作处理它们:

    Collection<Category> currentCopy = currentLevel.stream()
        .distinct()
        .collect(toList());

但似乎你试图在原地操纵集合而不是制作副本。 为此,您可以执行以下操作:

    Set<Category> result = new HashSet<>();
    currentLevel.removeIf(cat -> !result.add(cat));

请注意,这不是流操作,因此您无法并行运行它。 无论如何,你无法获得太多的并行性,因为谓词有副作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM