Quelle est la différence entre un prédicat et une Interface de fonction dans Java8?
je sais que cela peut être une question très simple sur mais je veux savoir quelle est la différence entre un Predicate
et <!-Interface dans Java8?
Predicate<String> predicateTest = (s)-> s.length() > 5;
System.out.println(predicateTest.test("Predicate"));
Function<String, Boolean> functionTest = str -> str.length()> 5;
System.out.println(functionTest.apply("Function"));
ici dans mon exemple les deux reviennent true
.La seule chose est que la façon d'appeler est différente ?
6 réponses
Différence entre Predicate<T>
et Function<T, R>
d'Abord et avant tout un Predicate<T>
strictement un boolean-valeur de la fonction:
_ _ _ _ _ _ _
| |
T --> | predicate | --> boolean
|_ _ _ _ _ _ _|
alors que ce n'est pas nécessairement vrai pour un Function<T, R>
:
_ _ _ _ _ _ _
| |
T --> | function | --> R
|_ _ _ _ _ _ _|
Le dernier consomme n'importe quel type d'objet comme Predicate<T>
active mais peut vary dans le type de retour.
cas D'utilisation de Predicate<T>
et Function<T, R>
Le cas d'utilisation de Predicate<T>
c'est quand vous besoin d'une fonction qui consomme un argument de type T
et renvoie un booléen. par exemple, cela peut être dans une situation où vous voulez filtrer un flux d'éléments, trouver le premier élément d'un flux qui satisfait une condition comme telle de .filter(predicate).findFirst()
, ou vérifier la présence d'un élément d'un flux qui satisfait à une certaine condition en tant que telle de anyMatch
,noneMatch
,allMatch
etc.
Le cas d'utilisation de Function<T, R>
c'est quand vous avez besoin d'une fonction qui consomme un argument de type T
et le transforme en un type R
par exemple, qui peut être lors de l'appel de stream.map(func)
.
explication de votre code snippet:
En ce qui concerne l'exemple extrait de code dans votre post Predicate<String>
et Function<String, Boolean>
sont la même chose en termes de ce qu'ils représentent, c'est à dire qu'ils représentent tous deux une fonction prenant un String
renvoi d'un boolean
. Cependant, le premier évite de boxe la valeur retournée de boolean
Boolean
alors que ce dernier ne le fait pas.
cela dit, cela ne signifie pas nécessairement partout où vous pouvez utiliser un Predicate<String>
vous pouvez également utiliser un Function<String, Boolean>
ou vice versa.
Exemple:
bien que cette compile:
Predicate<String> predicate = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(predicate);
Cela ne fonctionne pas:
Function<String, Boolean> function = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(function);
et vice versa:
Tout ceci fonctionne:
Function<String, Boolean> function = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(function);
Cela ne fonctionne pas:
Predicate<String> predicate = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(predicate);
dans ce cas il n'y a pas de différence, c'est important seulement pour les choses que vous pouvez appliquer à. Ainsi, par exemple,allMatch
attend un Predicate
, vous ne pouvez pas passer un Function
, même si, logiquement, ils font la même chose.
la réponse d'Aominè couvre les différences fondamentales. Je voudrais ajouter que les deux interfaces ont aussi des méthodes par défaut différentes, c'est-à-dire des méthodes que vous pouvez utiliser dans n'importe quelle classe d'implémentation:
Predicate<T>
Predicate<T> and(Predicate<? super T> other)
- renvoie un prédicat composé qui représente un court-circuitage logique et de ce prédicat et d'un autre.Predicate<T> or(Predicate<? super T> other)
- retourne un prédicat composé qui représente un court-circuitage logique ou de ce prédicat et de l'autre.negate()
- Retourne un prédicat qui représente la négation logique de ce prédicat.
Function<T,R>
<V> Function<T,V> andThen(Function<? super R,? extends V> after)
- renvoie une fonction composée qui applique d'abord cette fonction à son entrée, puis applique leafter
fonction du résultat.<V> Function<V,R> compose(Function<? super V,? extends T> before)
- renvoie une fonction composée qui applique d'abord lebefore
fonction à son entrée, puis applique cette fonction du résultat.
Comme vous pouvez le voir, Predicate
a des méthodes utiles pour créer des conditions complexes, un peu comme les opérateurs que vous utiliseriez dans un if
déclaration, alors que Function
a des méthodes qui supportent le chaînage simple.
Predicate
ne peut retourner un boolean
(résultat du test()
) tandis que Function
fait une transformation et peut retourner n'importe quoi (résultat de apply()
).
Predicate
sert à tester une condition.
Function
est utilisé pour faire la transformation.
il n'y a vraiment pas de différence.
En théorie, il ne devrait pas y avoir de différence fonctionnelle entre Predicate<T>
et Function<T, Boolean>
. Predicate
est juste une fonction qui prend un objet d'un certain type et retourne un booléen. Function
est une généralisation qui peut renvoyer n'importe quel type, pas seulement Boolean
.
il peut y avoir des détails d'implémentation dans Java lui-même qui les rendent distincts, mais ils devraient être les mêmes en théorie.
un exemple serait si un interface ne pouvait accepter qu'un Predicate<String>
, pas Function<String, Boolean
.
d'un point de vue technique, un Predicate<T>
n'est qu'une fonction de prendre un T
et retour d'un résultat primitif booléen. Cependant, du point de vue de l'usage, un Predicate<T>
est totalement une notion différente de celle d'un Function<T, Boolean>
.
Nous utilisons un Predicate<T>
pour effectuer une opération de filtrage, dans un stream par exemple, nous prenons un Stream<T>
taille n
, filtrer en utilisant un Predicate<T>
pour obtenir un flux de données de taille inférieure ou égale à n
. Pendant ce temps, un Function<T, Boolean>
dans un stream est utilisé pour effectuer une opération de cartographie de transformer un Stream<T>
dans un Stream<Boolean>
.
Comme vous pouvez le voir, Predicate<T>
et Function<T, Boolean>
sont techniquement identiques (en ignorant l'emballage Boolean
pour plus de simplicité), mais dans un contexte spécifique (stream par exemple), il est totalement une autre histoire que chacun d'eux joue un rôle distinct.