我有一个包含其他对象列表的对象,该对象包含另一个对象列表。非常像DTO。 在这些对象中,有一个其他类型的对象的列表,如果对象包含特定的String,我想在其中删除该元素。
例如
CustomerDTO customerDTO = CustomerTransformer.transformCustomer(custom);
List<InfoDTO> info = customerDTO.getInfo();
info(infoDTO -> {
List<MoreDTO> d = infoDTO.getMore();
for (MoreDTO moreDTO : d) {
List<ChannelDTO> channels = MoreDTO.getChannels();
for (ChannelDTO cdto : contentChannels) {
if ("apple".equals(cdto.getId())) {
moreDTO.getChannels().remove(cdto);
}
}
}
});
但是,实际上这似乎并不高效,并且可能会更改null指针吗?有更好的书写方式吗?在流中使用流和使用过滤器会有所帮助吗?
我是Java的新手。
答案 0 :(得分:2)
在迭代/循环时,您无法从列表中删除元素,会有一个ConcurrentModificationException
为避免这种情况,您可以通过这种方式在此处使用Java 8 Filter-
contentChannels = contentChannels
.stream()
.filter(cdto->(!"apple".equals(cdto.getId())))
.collect(Collectors.toList());
另一个选择是使用removeIf()
答案 1 :(得分:2)
上面的代码不起作用,请参阅@JB Nizet注释,
Triggering a ConcurrentModificationException
从本质上讲,当我们迭代的内容被修改时,ConcurrentModificationException用来快速失败。让我们通过一个简单的测试来证明这一点:
List<Integer> integers = newArrayList(1, 2, 3);
for (Integer integer : integers) {
integers.remove(1);
}
因此您可以使用forEach
和removeIf
来避免ConcurrentModificationException
List<InfoDTO> info = customerDTO.getInfo();
info.forEach(more->more.getMore().forEach(channelDto->channelDto.getChannels().removeIf(cdto->"apple".equals(cdto.getId()))));
或者如果您只有List<ChannelDTO>
List<ChannelDTO> channels = MoreDTO.getChannels();
channels.removeIf(cdto->"apple".equals(cdto.getId()));