我有一个 GroupOffices
的列表List<GroupOffice> officesOfTheGroup;
我想搜索id是否等于 groupOffice.getId (长值),但标签为 groupOffice.getLabel (字符串),并将其分配给布尔值。下面的代码运行良好,但是有没有比使用for循环遍历所有项目更好的方法了?
public GroupOfficeDto saveGroupOffice(GroupOfficeDto groupOfficeDto) {
List<GroupOffice> officesOfTheGroup = //some list from db..
for (GroupOffice go : officesOfTheGroup) {
if ((!go.getId().equals(groupOfficeDto.getId())) && go.getLabel().equals(groupOfficeDto.getLabel())) {
return groupOfficeDto;
}
return null:
}
或者我怎样才能使用流?如果是这样,使用流是更好的方法吗?
注意:我正在使用Java8
答案 0 :(得分:4)
如果您需要布尔值,可以执行以下操作:
boolean b = officesOfTheGroup.stream()
.anyMatch(office -> !office.getId().equals(5) && office.getLabel().equals("London"))
答案 1 :(得分:2)
有没有比
for
循环遍历所有项目更好的方法了?
值得注意的是,如果代码在到达列表末尾之前找到了可接受的代码,则不会遍历所有项目。但是,如果只有列表可以使用,那么除了准备检查每个列表元素之外别无选择。至于是否使用for
循环,我认为这只是罚款。
或者我怎样才能使用流?如果是这样,使用流是更好的方法吗?
这些天来使用流确实确实很时髦,尽管它们的使用似乎超出了我的想象,但您的使用并不是一个合理的用例。您可以这样写:
public GroupOfficeDto saveGroupOffice(GroupOfficeDto groupOfficeDto) {
List<GroupOffice> officesOfTheGroup = //some list from db..
Integer officeId = groupOfficeDto.getId();
String officeLabel = groupOfficeDto.getLabel();
return officesOfTheGroup.stream()
.filter(o -> !o.getId().equals(officeId))
.anyMatch(o -> o.getLabel().equals(officeLabel))
? groupOfficeDto : null;
}
此处特别相关的是使用.anyMatch()
终端操作,因为它允许在确定结果后立即完成流处理,例如for
循环,而不是处理整个流。还要注意,要与之进行比较的ID和标签是在流表达式之前提取并存储在变量中的。这使它们可以“有效地最终化”,这是它们出现在流中的lambda中所必需的。以这种方式进行操作也效率更高,而不是一次又一次地从DTO检索相同的对象-同样适用于for
循环情况。
请注意,流版本并不比循环版本简单得多,并且阅读也不容易。我没有亲眼看到太多优势,无论是一个比其他。
答案 2 :(得分:1)
尝试一下:
public GroupOfficeDto saveGroupOffice(GroupOfficeDto groupOfficeDto) {
...
List<GroupOffice> result = officesOfTheGroup.stream()
.filter(it -> it.getLabel().equals(groupOfficeDto.getLabel()))
.filter(it -> !it.getId().equals(groupOfficeDto.getId()))
.collect(Collectors.toList())
...
}