有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何将BiPredicate与anyMatch()一起使用

我有一组货币作为Set<String>,需要的货币作为Set<String>。我必须检查所需的货币是否存在于货币集合中。我已经为此写了BiPredicate,如下所示,并试图在anyMatch()中使用相同的内容。但这对我不起作用。我怎样才能做到这一点

Set<String> currencyValues = currencies.getCurrencies().values()
                    .stream()
                    .map(currencyEntity -> {
                       return currencyEntity.getNameOfSymbol();
                    }).collect(Collectors.toSet());

Set<String> requestCurrencyCodes = globalPricingRequests.stream().map(globalPricingRequest -> {
    return globalPricingRequest.getCurrencyISOCode();
}).collect(Collectors.toSet());

BiPredicate<Set<String>, String> checkIfCurrencyPresent = Set::contains;

boolean isCurrencyCodeValid = requestCurrencyCodes.stream().anyMatch(checkIfCurrencyPresent.test(currencyValues));

我无法在^{中传递requestCurrencyCode


共 (4) 个答案

  1. # 1 楼答案

    你不需要一个BiPredicate。相反,一个简单的Predicate就可以做到这一点

    Predicate<String> checkIfCurrencyPresent = currencyValues::contains;
    
    boolean isCurrencyCodeValid = requestCurrencyCodes.stream()
            .anyMatch(checkIfCurrencyPresent);
    

    这是一个更精简的版本

    boolean isCurrencyCodeValid = requestCurrencyCodes.stream()
            .anyMatch(currencyValues::contains);
    
  2. # 2 楼答案

    再加上目前为止提供的好答案。您可以通过Collections.disjoint实现上述要求:

    boolean isCurrencyCodeValid = !Collections.disjoint(currencyValues, requestCurrencyCodes);
    

    如果requestCurrencyCodes中存在currencyValues中的任何值,则isCurrencyCodeValid将为真,否则为假

    完整代码:

    Set<String> currencyValues = currencies.getCurrencies().values()
                                  .stream()
                                  .map(CurrencyEntity::getNameOfSymbol)
                                  .collect(toSet());
    
    Set<String> requestCurrencyCodes = globalPricingRequests.stream()
            .map(GlobalPricingRequest::getCurrencyISOCode)
            .collect(toSet());
    
    boolean isCurrencyCodeValid = !Collections.disjoint(currencyValues, requestCurrencyCodes);
    
  3. # 3 楼答案

    ^{}方法采用的是Predicate,而不是BiPredicate。因此,不能将BiPredicate直接与anyMatch一起使用。从您展示的代码来看,您无论如何都不需要BiPredicate。只要做:

    boolean isCurrencyCodeValid = requestCurrencyCodes.stream()
            .anyMatch(currencyValues::contains);
    

    如果出于某种原因确实想使用BiPredicate,可以执行以下操作:

    BiPredicate<Set<String>, String> checkIfCurrencyPresent = Set::contains;
    boolean isCurrencyCodeValid = requestCurrencyCodes.stream()
            .anyMatch(code -> checkIfCurrencyPresent.test(currencyValues, code));
    

    然而,我不知道你为什么要这么做。它所做的只是将一个BiPredicate包装在一个Predicate

  4. # 4 楼答案

    虽然理想情况下,我最好在这里使用preferred using ^{},但是如果您要创建一个可在多种情况下使用的通用方法,您可以使用以下实用方法避免在Predicate中使用BiPredicate的包装:

    private static boolean checkIfCurrencyPresent(Set<String> set, String currency) {
        return set.contains(currency);
    }
    

    然后使用lambda将其消费为:

    boolean isCurrencyCodeValid = requestCurrencyCodes
            .stream()
            .anyMatch(a -> checkIfCurrencyPresent(currencyValues,a));
    

    这样,它就不依赖于针对特定的Set测试字符串,并且您可以将其广泛地用作:

    boolean isCurrencyCodeValidInverseExample = currencyValues // any collcetion of string
            .stream()
            .anyMatch(a -> checkIfCurrencyPresent(requestCurrencyCodes, a)); // different set as an input
    

    旁白:代码的前两行可能会变得更可读,例如(假设模型名):

    Set<String> currencyValues = currencies.getCurrencies().values()
            .stream()
            .map(CurrencyEntity::getNameOfSymbol)
            .collect(Collectors.toSet());
    
    Set<String> requestCurrencyCodes = globalPricingRequests.stream()
            .map(GlobalPricingRequest::getCurrencyISOCode)
            .collect(Collectors.toSet());