Java 8偷看vs地图

我有以下案例:有一个对象列表 – ProductData包含几个字段:

public class ProductData { .... private String name; private String xref; //getters //setters } 

并且有API返回以下对象的列表:

 public class RatingTableRow { private String planName; private String planXref; private int fromAge; private int toAge; private int ratingRegion; //constructor //getters //setters } 

但它返回具有空计划名称字段的对象,因为在提取此对象期间不允许这样做。 我需要通过外部参照将产品数据与RatingTableRow链接,以便将计划名称设置为RatingTableRow,因为我需要稍后使用此对象,因此我创建了以下代码来执行此操作:

 Map productByXref = plans.stream() .collect(toMap(ProductData::getInternalCode, Function.identity())); return getRatingTableRows(...).stream .filter(ratingRow -> productByXref.containsKey(ratingRow.getPlanXref())) .peek(row -> { ProductData product = productByXref.get(row.getPlanXref()); row.setPlanName(product.getName()); })....; 

我知道java文档说peek不适合这些需求,但想要以更正确的方式获得有关如何完成此任务的建议。

记录的原因主要是出于调试目的

最终在peek内部处理的东西可能根本不符合终端操作的条件,并且流仅由终端操作执行。

首先假设一个简单的例子:

  List list = new ArrayList<>(); List result = Stream.of(1, 2, 3, 4) .peek(x -> list.add(x)) .map(x -> x * 2) .collect(Collectors.toList()); System.out.println(list); System.out.println(result); 

一切看起来都不错吧? 因为peek将在这种情况下运行所有元素 。 但是当你添加一个filter时会发生什么(并忘记peek ):

  .peek(x -> list.add(x)) .map(x -> x * 2) .filter(x -> x > 8) // you have inserted a filter here 

你正在为每个元素执行peek ,但是没有收集任何元素。 你确定你想要吗?

这可能变得更加棘手:

  long howMany = Stream.of(1, 2, 3, 4) .peek(x -> list.add(x)) .count(); System.out.println(list); System.out.println(howMany); 

在java-8中填充了列表, 但在jdk-9中根本没有调用peek 。 由于您没有使用filterflatmap您不会修改Stream的大小,并且只需要它的大小; 因此,根本没有被称为偷看 。 因此,依赖peek是一个非常糟糕的策略。