我有以下案例:有一个对象列表 - ProductData包含几个字段:
public class ProductData
{
....
private String name;
private String xref;
//getters
//setters
}
Run Code Online (Sandbox Code Playgroud)
并且有API返回以下对象的列表:
public class RatingTableRow
{
private String planName;
private String planXref;
private int fromAge;
private int toAge;
private int ratingRegion;
//constructor
//getters
//setters
}
Run Code Online (Sandbox Code Playgroud)
但它返回具有空计划名称字段的对象,因为在提取此对象期间不允许这样做.我需要通过外部参照将产品数据与RatingTableRow链接,以便将计划名称设置为RatingTableRow,因为我需要稍后使用此对象,因此我创建了以下代码来执行此操作:
Map<String, ProductData> 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());
})....;
Run Code Online (Sandbox Code Playgroud)
我知道java文档说这peek不符合这些需求,但希望得到关于如何以更正确的方式完成此任务的建议.
Eug*_*ene 49
peek记录的原因主要是用于调试目的.
最终在内部处理的东西peek可能根本不符合终端操作的条件,并且流仅由终端操作执行.
首先假设一个简单的例子:
List<Integer> list = new ArrayList<>();
List<Integer> 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);
Run Code Online (Sandbox Code Playgroud)
一切看起来都不错吧?因为在这种情况下peek将运行所有元素.但是当你添加一个filter(并忘记做了什么peek)时会发生什么:
.peek(x -> list.add(x))
.map(x -> x * 2)
.filter(x -> x > 8) // you have inserted a filter here
Run Code Online (Sandbox Code Playgroud)
您正在peek为每个元素执行,但不收集任何元素.你确定你想要吗?
这可能变得更加棘手:
long howMany = Stream.of(1, 2, 3, 4)
.peek(x -> list.add(x))
.count();
System.out.println(list);
System.out.println(howMany);
Run Code Online (Sandbox Code Playgroud)
在java-8中填充了列表,但在jdk-9中 peek根本没有调用.由于您没有使用filter或者flatmap您没有修改Stream count的大小而只需要它的大小; 因此,根本没有调用.因此,依靠peek是一个非常糟糕的策略.
| 归档时间: |
|
| 查看次数: |
15126 次 |
| 最近记录: |