4
votes

Comment utiliser BiPredicate avec anyMatch ()

J'ai un ensemble de devises comme Set et RequiredCurrency comme Set . Je dois vérifier si l'une des devises requises est présente ou non dans la devise définie. J'ai écrit BiPredicate pour cela comme ci-dessous et j'essaie d'utiliser la même chose dans anyMatch () . Mais cela ne fonctionne pas pour moi. Comment puis-je y parvenir.

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));

Je ne parviens pas à transmettre le requestCurrencyCode dans checkIfCurrencyPresent.test(currencyValues).


3 commentaires

Stream.anyMatch prend un Predicate , pas un BiPredicate . Cela dit, l'utilisation de anyMatch (currencyValues ​​:: contains) devrait répondre à vos besoins.


anyMatch obtient Predicate comme argument. vous devez donc passer Predicate à la place BiPredicate


C'est la raison exacte pour laquelle j'ai suggéré si vous avez besoin d'un prédicat , comment vous pourrait l'utiliser. . Donc précisément, vous aviez juste besoin d'un Predicate dans votre cas d'utilisation actuel et non d'un BiPredicate .


4 Réponses :


1
votes

Vous n'avez pas besoin d'un BiPredicate . Un simple Predicate le ferait.

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

Et voici une version plus condensée.

Predicate<String> checkIfCurrencyPresent = currencyValues::contains;

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


1 commentaires

Et si je souhaite utiliser un biprédicat?



1
votes

Le La méthode Stream.anyMatch prend un Predicate , pas un BiPredicate . Par conséquent, vous ne pouvez pas utiliser un BiPredicate directement avec anyMatch . D'après le code que vous avez montré, vous n'avez de toute façon pas besoin d'un BiPredicate . Faites simplement:

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

Si vous voulez vraiment utiliser un BiPredicate pour une raison quelconque, vous pouvez faire:

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

Cependant, je ne sais pas pourquoi vous voudriez faire ça. Tout ce qu'il fait, c'est envelopper un BiPredicate dans un Predicate.


0 commentaires

1
votes

Dans l'idéal, j'aurais aussi a préféré utiliser Predicate ici, mais si vous deviez créer une méthode générique qui pourrait être utilisée dans plusieurs situations, vous auriez pu vous épargner le encapsulation de BiPredicate dans un Predicate en utilisant la méthode utilitaire suivante:

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

Set<String> requestCurrencyCodes = globalPricingRequests.stream()
        .map(GlobalPricingRequest::getCurrencyISOCode)
        .collect(Collectors.toSet());

, puis consommé en utilisant un lambda comme :

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

de sorte qu'il ne repose pas sur le test d'une chaîne par rapport à un Set spécifique et que vous puissiez l'utiliser de manière assez générique comme: p >

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

À part : Les deux premières lignes de votre code pourraient éventuellement être rendues plus lisibles comme quelque chose comme (en supposant que le modèle noms):

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


0 commentaires

0
votes

Juste pour ajouter les bonnes réponses fournies jusqu'à présent. vous pouvez accomplir cette exigence via Collections.disjoint:

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);

isCurrencyCodeValid sera vraie si une valeur dans currencyValues ​​ code> est présent dans requestCurrencyCodes sinon false.

Code complet:

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


0 commentaires