我有DTO,其中包含多个类型为ArrayList
的属性。
ArrayList
获取属性。ArrayList
最后返回修改后的DTO
public class SomeDTO{
private String attrOne;
private String attrTwo;
private List<SomeOtherDataType> listAttr;
// getters
// setter
...
}
// This is the method where I want to modify the DTO
private void modifyDTO(SomeDTO someDTO){
someDTO.getlistAttr()
.stream()
/// need help here, how to remove some element from list
/// based on some condition.
/// note the changes in the list should be reflected in DTO
}
这可以通过简单地执行forEach终端操作来完成,但是有没有更好的方法可以做到这一点或其他人遵循的最佳实践呢?
谢谢
答案 0 :(得分:4)
实际上,您有两种方法:
收集包含要保留的元素的新列表并将其分配给字段
从实际列表中删除元素
第二种方法可能是您出于多种原因所需的:
通常对于List
字段,您不想创建新的List来更改其状态。您只希望针对引用不可变对象的字段。
如果某些对象在List
字段上保留引用,则这些对象将引用旧对象。这是不希望的,并且会产生难以理解的副作用。
创建整个过滤后的对象可能会占用CPU /内存,而从现有的List
中删除对象可能会更有效。
1种方式)重新分配给一个新对象
List<SomeOtherDataType> listAttr =
someDTO.getlistAttr()
.stream()
.filter(o -> conditionToKeep)
.collect(Collectors.toList());
someDTO.setListAttr(listAttr);
2种方式)过滤当前对象
someDTO.getlistAttr().removeIf(o -> conditionToRemove);
编辑关于OP注释
即使要过滤出元素的条件需要在SomeOtherDataType
对象及其组成元素上进行挖掘,仍然不需要流。
精美的代码来说明这一点:
someDTO.getlistAttr()
.removeIf(o -> {
Bar bar = o.getFoo().getBar();
if (bar != null){
List<FooBar> fooBars = bar.getList();
if (fooBars.contains(...)){
return true; // I remove in this case
}
}
return false; // in any other case I keep
}
);
答案 1 :(得分:1)
这里不需要使用流。您可以简单地使用Collection.removeIf。
来自javadoc(重点是我的)
删除此集合中满足给定谓词的所有元素。在迭代过程中或谓词中引发的错误或运行时异常将中继给调用方。
因此,你可以写
someDTO.getlistAttr().removeIf((someOtherDataType) -> /*Your logic here*/)
如果您真的想使用Streams,那么从离开的地方开始,您可以使用filter
并收集通过过滤器的SomeOtherDataType
元素作为列表。
List<SomeOtherDataType> filterdList = someDTO.getlistAttr()
.stream()
.filter(someOtherDataType -> /* your logic */)
.collect(Collectors.toList())
但是在此之后,您要么必须
使用上述SomeDTO
(filterdList
) 1 或
new SomeDTO(someDTO.getAttrOne(), someDTO.getAttrTwo(), filterdList)
使用listAttr
(filterdList
)设置现有的someDTO.setListAttr(filterdList)
1 我认为您的意思是第二个实例变量的名称为attrTwo
。