【问题标题】:Filter Predicate for EqualsIngnoreCaseEqualsIgnoreCase 的过滤谓词
【发布时间】:2021-05-17 20:32:44
【问题描述】:

我正在尝试为 Object is NotNull 和 EqualsIgnoreCase 编写过滤谓词,但我无法为 EqualsIgnorecase 部分创建谓词。能不能给点建议。

我的代码是:

 basicDetailentity.forEach(prj -> {
      CharlieAddress billToAddress = addressList.stream()
          .filter(add -> Objects.nonNull(add.getSiteDuns())
              && add.getSiteDuns().equalsIgnoreCase(prj.getBillToDuns())
              && Objects.nonNull(add.getOrgName())
              && add.getOrgName().equalsIgnoreCase(prj.getOperatingUnit()))
          .findFirst().orElse(null);

我已经为 nonNull 部分创建了 2 个谓词,但发现很难为 equalsIgnoreCase 部分创建一个,任何建议都会有所帮助

  public static final Predicate<CharlieAddress> CHARLIE_ADDRESS_DUNS_PRESENT =
      add -> Objects.nonNull(add.getSiteDuns());

  public static final Predicate<CharlieAddress> CHARLIE_ADDRESS_ORG_PRESENT =
      add -> Objects.nonNull(add.getOrgName());

【问题讨论】:

  • 当然..谢谢你的建议..欣赏它。
  • 所有这些类的结构是什么?我们应该猜?
  • 使用Objects.nonNull(…) 代替简单的… != null 没有任何改进。除此之外,您的代码缺乏有用的目的。第一个代码片段甚至没有编译,但即使你添加了缺少的括号,它也会是 forEach 中的一个值生成表达式,它只会删除每个值。

标签: java filter java-8 predicate


【解决方案1】:

问题是您的条件依赖于两个参数。您需要 address 并且需要 prj (项目?- 这个答案的其余部分假设如此)。

add.getSiteDuns().equalsIgnoreCase(prj.getBillToDuns())
 ^                                  ^

谓词接受一个 single 参数并返回一个布尔值,所以除非你有一个 lambda 作为闭包,它从封闭范围中捕获一些变量(如果你希望谓词是静态字段,你可能)那么你所要求的就是不可能的

final Project prj = /*something*/; // must be final or "effectively final"
Predicate<CharlieAddress> foo =
    add -> add.getSiteDuns().equalsIgnoreCase(prj.getBillToDuns());
                                            // ^ captured

还有另一个接口,BiPredicate,它接受 2 个参数。也许这就是你要找的。​​p>

BiPredicate<CharlieAddress, Project> foo =
    (add, prj) -> add.getSiteDuns().equalsIgnoreCase(prj.getBillToDuns());

你没有问,但你现有的谓词可以用!= null简化

public static final Predicate<CharlieAddress> CHARLIE_ADDRESS_DUNS_PRESENT =
    add -> add.getSiteDuns() != null;

public static final Predicate<CharlieAddress> CHARLIE_ADDRESS_ORG_PRESENT =
    add -> add.getOrgName() != null;

【讨论】:

    【解决方案2】:

    如果我可以假设addressList 中的对象对于prj.getBillToDuns()prj.getBillToDuns() 永远不会有空值,那么您的代码可以简化为

    basicDetailentity.forEach(prj -> {
      CharlieAddress billToAddress = addressList.stream()
          .filter(add -> Objects.nonNull(add.getSiteDuns())
              && add.getSiteDuns().equalsIgnoreCase(prj.getBillToDuns())
              && Objects.nonNull(add.getOrgName())
              && add.getOrgName().equalsIgnoreCase(prj.getOperatingUnit()))
          .findFirst().orElse(null);
    

    basicDetailentity.forEach(prj -> {
      CharlieAddress billToAddress = addressList.stream()
          .filter(add -> prj.getBillToDuns().equalsIgnoreCase(add.getSiteDuns())
              && prj.getOperatingUnit().equalsIgnoreCase(add.getOrgName()))
          .findFirst().orElse(null);
    

    或者如果你被允许使用Apache Common Collections中的StringUtils,那么它可以很简单

    basicDetailentity.forEach(prj -> { 
      CharlieAddress billToAddress = addressList.stream()
      .filter(add -> StringUtils.equalsIgnoreCase(add.getSiteDuns(), prj.getBillToDuns())
          && StringUtils.equalsIgnoreCase(add.getOrgName(), prj.getOperatingUnit()))
      .findFirst().orElse(null);
    

    如果您仍然只想自己做,请创建一个实用方法,它接受两个字符串作为参数并返回 true,如果它们都不为 null 且相等,则忽略大小写。然后将其用作过滤器中的谓词

    private boolean myEqualsIgnoreCase(String oneStr, String twoStr) {
        return oneStr != null && twoStr != null && oneStr.equalsIgnoreCase(twoStr);
    }
    
    basicDetailentity.forEach(prj -> { 
      CharlieAddress billToAddress = addressList.stream()
      .filter(add -> myEqualsIgnoreCase(add.getSiteDuns(), prj.getBillToDuns())
          && myEqualsIgnoreCase(add.getOrgName(), prj.getOperatingUnit()))
      .findFirst().orElse(null);
    

    注意

    除了上面的解释之外,我相信这段代码对于大型集合来说效率不是很高,如果我是你,我会为 addressList 实现某种基于 Key-Value 的搜索逻辑,这样我就可以提供一个包含SiteDunesOrgName 然后 map(Key-Value) 会返回对应的地址对象作为值。

    【讨论】:

    • 所以这个答案已经被编辑,只是为了删除下面的文字“我希望它有帮助,如果有,请投票”,评论说“修剪聊天”,真的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多