【问题标题】:How to filter data on a list according to multiple parameters in Java?如何根据Java中的多个参数过滤列表中的数据?
【发布时间】:2019-06-26 12:18:35
【问题描述】:

我有一个 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

【问题讨论】:

  • 我想搜索 id 是否等于 5 但标签不是 London 并将其分配给布尔值您的代码会相反。
  • 我很困惑。您提供的代码似乎执行了与您描述的代码相反的测试。
  • 感谢 cmets 我编辑了问题。代码是正确的

标签: java list java-8 stream java-stream


【解决方案1】:

有没有更好的方法,而不是使用 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 循环情况也是如此。

请注意,流版本并不比循环版本简单得多,也不容易阅读。我个人认为两者都没有太大优势。

【讨论】:

  • 哦,有一个错误:在任何匹配中的“o.getLabel()”上,o 没有解析变量错误..你能解决这个错误吗?
  • @ChrisGarsonn,我想你可能已经自己弄清楚了,但是在我的代码中留下错误对我来说是一种糟糕的形式。固定。
【解决方案2】:

试试这个:

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())
    ...
}

【讨论】:

  • 当我使用一些 dto.getId 和 to.getLabel 而不是 London 和 5 时,它给出了关于它必须是最终的错误。如何使用参数而不是这些硬编码值?
【解决方案3】:

如果你需要布尔值,你可以这样做:

boolean b = officesOfTheGroup.stream()
    .anyMatch(office -> !office.getId().equals(5) && office.getLabel().equals("London"))

【讨论】:

  • 这里的“办公室”是什么?它没有定义?
  • @ChrisGarsonn 抱歉,这是 lambda 参数。刚刚编辑
  • 当我使用一些 dto.getId 和 to.getLabel 而不是 London 和 5 时,它给出了关于它必须是最终的错误。我如何使用参数而不是这些硬编码值?
  • lambda 表达式中使用的变量必须是最终的或有效的最终...错误是这样的。
  • @ChrisGarsonn 在循环之前,您是否在方法内为 groupOfficeDto 分配了任何值?
猜你喜欢
  • 2020-04-09
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
相关资源
最近更新 更多