筛选equalsIgnoreCase的谓词



我正试图为Objects.nonNullequalsIgnoreCase编写一个筛选器谓词,但无法为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部分创建了两个谓词,但我发现很难为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());

问题是您的条件依赖于两个参数。您需要地址,还需要prj(项目?——本答案的其余部分假设是这样(。

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

谓词接受一个单个参数并返回一个布尔值,因此,除非您有一个充当闭包的lambda,它从封闭作用域捕获一些变量(如果您希望谓词是一个静态字段,则可能(,否则您所要的是不可能的

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

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

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;

如果我可以假设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);

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

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实现某种基于键值的搜索逻辑,这样我就可以提供一个包含SiteDunesOrgName的键,然后map(键值(会返回相应的地址对象作为值。

最新更新