2017-03-18 1 views
0

permet de dire que nous avons un Predicate et un Function -Interface:Java 8: Je ne comprends pas la façon dont Java implémente des interfaces fonctionnelles

Function<String, String> function = null; 
Predicate<String> predicate = null; 

Maintenant, je veux donner le Predicate -Interface une référence de méthode où le type de retour est un boolean et dans notre cas le paramètre une chaîne. Mais pourquoi la référence de méthode suivante semble être droite:

Predicate<String> predicate = String::isEmpty; 

Le isEmpty -method n'a pas String-paramètre, bien que le Predicate -Interface nécessite une chaîne de paramètres. Pourquoi est-ce toujours juste? Est-ce que je manque quelque chose?

Un autre exemple: L'interface de fonction renvoie dans notre cas une chaîne et prend une chaîne comme paramètre. Mais la référence de méthode suivante semble erroné:

Function<String, String> function = String::concat; //wrong 

La Concat-Méthode a une chaîne en tant que paramètre et renvoie une chaîne. Pourquoi c'est faux?

J'espère que quelqu'un peut me l'expliquer.

+0

Votre question concerne vraiment les références de méthodes plutôt que les interfaces fonctionnelles. Je vous recommande de lire https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html Il explique les quatre types de références de méthodes et les expressions lambda pour lesquelles elles sont des raccourcis. – sprinter

Répondre

3

Lorsque vous utilisez une référence de méthode sur une méthode d'instance, le récepteur de méthode devient le premier argument. Alors

String::isEmpty 

est équivalent à

(String str) -> str.isEmpty() 

et

String::concat 

est équivalent à

(String a, String b) -> a.concat(b) 

... qui ne correspond pas au type de Function.

+1

Pour être complet, il peut être utile d'ajouter un exemple de référence à une méthode d'instance d'un objet particulier. Par exemple 'myString :: concat' est équivalent à' (String a) -> myString.concat (a) '. – sprinter

0

La raison pour laquelle

Function<String, String> function = String::concat; 

ne compile pas est parce qu'il est équivalent à (comme Louis écrit)

Function<String, String> function = (String a, String b) -> a.concat(b); 

alors que Function.apply(T t) prend un seul argument (t) et vous passez une fonction cela prend deux arguments (a et b).

0

String::isEmpty peut, en théorie, signifier une de deux choses.

  1. Méthode statique dans la classe String:

    s -> String.isEmpty(s) 
    
  2. Une méthode d'instance dans la classe String:

    (String s) -> s.isEmpty() 
    

Votre cas tombe dans # 2.

De même, String::concat peut vouloir dire deux choses. Il est

(s1, s2) -> String.concat(s1, s2) 

ou

(String s1, String s2) -> s1.concat(s2) // Your case 

(Cependant, ce n'est pas un Function<String, String>, car il ne tient pas exactement un argument, cependant, un BinaryOperator<String>.)