使用Java流式API从list.forEach返回列表
我有一个POJO:使用Java流式API从list.forEach返回列表,java,java-stream,Java,Java Stream,我有一个POJO: class MyObject { private Double a; private String b; //constructor, getter + setter } 某些函数正在创建此POJO的列表。a的某些值可能为空,因此我想将它们替换为0.0。目前我正在这样做 public List<MyObject> fetchMyObjects(Predicate predicate) { List<MyObject>
class MyObject {
private Double a;
private String b;
//constructor, getter + setter
}
某些函数正在创建此POJO的列表。a
的某些值可能为空,因此我想将它们替换为0.0。目前我正在这样做
public List<MyObject> fetchMyObjects(Predicate predicate) {
List<MyObject> list = getMyListsOfTheDatabase(predicate);
list
.forEach(myObject -> {
if (myObject.getA() == null) {
myObject.setA(0.0);
}
});
return list;
}
这不是关于将空值转换为零的最佳位置,而是关于如何更好地理解流式api的问题。
forEach
没有返回值,因此您可能要查找的是map
return list
.stream()
.map(e -> {
if (e.getA() == null) e.setA(0d);
return e;
})
.whateverElse()...
不能使用单个语句返回相同的
List
实例,但可以返回包含相同(可能已修改)元素的新List
实例:
return list.stream()
.map(myObject -> {
if (myObject.getA() == null) {
myObject.setA(0.0);
}
return myObject;
})
.collect(Collectors.toList());
使用函数
返回一个由该流的元素组成的流,在从结果流中消耗元素时,对每个元素执行提供的操作
public List fetchMyObjects(谓词){
返回getMyListsOfTheDatabase(谓词)
.stream()
.peek(it->if(it.getA()==null)it.setA(0.0))
.collect(Collectors.toList());
}
实际上,您应该使用List::replaceAll
:
list.replaceAll(x -> {
if(x.getA() == null) x.setA(0.0D);
return x;
})
以下情况可以:
list.stream()
.filter(obj -> obj.getA() == null)
.forEach(obj -> obj.setA(0.0));
return list;
但是,在您的情况下,仅返回流可能更合适(取决于):
公共流fetchMyObjects(谓词){
返回getMyListsOfTheDatabase(谓词);
}
公共流StreamMyObject(列表){
return list.stream()
.peek(对象->{
if(obj.getA()==null){
目标毛(0.0);
}
});
}
我个人从未使用过peek
,但在这里它修正了值
关于代码约定,在java社区中它们更像字符串:
- 缩进:Java将4作为更独立的方法,而不是C++的3, 预计压痕会减少。有争议但没问题
- 对于泛型类型参数,通常使用单个大写字母,如
T、C、S
- 对于lambda参数,短名称通常是一个字母,因此我使用了
obj
- 当其他人很乐意回答你的问题时,请允许我退一步,给你你没有要求的答案(但可能是你想要的答案):你不想这样做。流操作应该没有副作用。您所要求的正是一个流操作,它的副作用是修改进入流中的原始对象。这是一种糟糕的代码风格,可能会让那些在您之后阅读您的代码的人感到困惑
您已经拥有的代码比任何组合流管道都能更好地解决您的问题
如果您可以修改POJO,您可能需要的是,如果从数据库中检索到
null
,则将a
设置为0的构造函数,或者可以从列表调用的方法。forEach
:
list.forEach(MyObject::setAToZeroIfNull);
这不是关于,如果这是将空值转换为空值的最佳位置
零,而是一个更好地理解流式api的问题
这很公平。在任何情况下,我都会让这个答案代表任何其他突然出现的人。与
list.forEach()
相比,它有什么优势?(在我看来,这只是更加冗长/可读性较差。)@OleV.V。我想你是对的,这只是我的习惯。这是一个非常非常糟糕的建议<在这种情况下,可能根本不执行code>peek,因为不需要它。您能解释一下原因吗?在java-9中运行Stream.of(1,2,3,4).map(x->{System.out.println(x);返回x+1;}).count()
。同样的道理,在这个流中,您所关心的只是一个基于getMyListsOfTheDatabase
计算的列表;但是您没有以任何形式更改输入,因此peek
可能会被完全丢弃。谢谢您的帖子,非常感谢。谢谢,效果很好。但是作为@OleV.V。写下,一个人不应该这样做:)
public Stream<MyObject> fetchMyObjects(Predicate predicate) {
return getMyListsOfTheDatabase(predicate);
}
public Stream<MyObject> streamMyObjects(List<MyObject> list) {
return list.stream()
.peek(obj -> {
if (obj.getA() == null) {
obj.setA(0.0);
}
});
}
list.forEach(MyObject::setAToZeroIfNull);