[英]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.