:: (deux points) opérateur en Java 8
J'ai été d'explorer la Java 8 source et trouvé cette partie de code très surprenant:
//defined in IntPipeline.java
@Override
public final OptionalInt reduce(IntBinaryOperator op) {
return evaluate(ReduceOps.makeInt(op));
}
@Override
public final OptionalInt max() {
return reduce(Math::max); //this is the gotcha line
}
//defined in Math.java
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Est Math::max
quelque chose comme une méthode de pointeur? Comment un normal static
méthode converties en IntBinaryOperator
?
C'est du sucre syntaxique pour le compilateur de générer automatiquement des implémentations d'interface basé sur la fonction que vous fournissez (pour rendre l'ensemble du lambda truc plus facile à utiliser avec du code existant bases).
java.dzone.com/articles/java-lambda-expressions-vs pourrait aider, n'avait pas l'air de profondeur dans le sujet
ce n'est pas exactement "sucre syntaxique", à moins que vous pouvez dire pour quoi. c'est à dire "x est sucre syntaxique pour y".
il crée un nouvel objet de lambda chaque fois que je l'utilise.
Les Lambdas et de la méthode références ne sont pas des "plain old anonyme intérieur des classes". Voir programmers.stackexchange.com/a/181743/59134 . Oui, si nécessaire, de nouvelles classes et des instances sont créées à la volée, si nécessaire, mais seulement si nécessaire.
java.dzone.com/articles/java-lambda-expressions-vs pourrait aider, n'avait pas l'air de profondeur dans le sujet
ce n'est pas exactement "sucre syntaxique", à moins que vous pouvez dire pour quoi. c'est à dire "x est sucre syntaxique pour y".
il crée un nouvel objet de lambda chaque fois que je l'utilise.
TestingLambda$$Lambda$2/8460669
et TestingLambda$$Lambda$3/11043253
ont été créés sur les deux invocations.Les Lambdas et de la méthode références ne sont pas des "plain old anonyme intérieur des classes". Voir programmers.stackexchange.com/a/181743/59134 . Oui, si nécessaire, de nouvelles classes et des instances sont créées à la volée, si nécessaire, mais seulement si nécessaire.
OriginalL'auteur Narendra Pathai | 2013-11-15
Vous devez vous connecter pour publier un commentaire.
Généralement, qu'on pourrait appeler le
reduce
méthode à l'aide deMath.max(int, int)
comme suit:Qui nécessite beaucoup de syntaxe pour appeler juste
Math.max
. C'est là que les expressions lambda entrent en jeu. Depuis Java 8, il est permis de faire la même chose en beaucoup plus court chemin:Comment cela fonctionne? Le compilateur java "détecte", que vous souhaitez mettre en œuvre une méthode qui accepte deux
int
s et renvoie unint
. C'est l'équivalent pour les paramètres formels d'une seule et unique méthode de l'interfaceIntBinaryOperator
(le paramètre de la méthodereduce
vous voulez l'appeler). Ainsi, le compilateur fait le reste pour vous, il a juste suppose que vous voulez mettre en œuvreIntBinaryOperator
.Mais comme
Math.max(int, int)
lui-même remplit les conditions de forme deIntBinaryOperator
, il peut être utilisé directement. Parce que Java 7 n'a pas de syntaxe qui permet à une méthode même d'être passé comme argument (vous ne pouvez passer des résultats de la méthode, mais jamais de la méthode de référence, la::
syntaxe a été introduite dans Java 8 pour les méthodes de référence:Noter que ce sera interprété par le compilateur, pas par la JVM au moment de l'exécution! Bien qu'elle produit différents bytecode pour tous les trois fragments de code, ils sont sémantiquement égaux, de sorte que les deux dernières peuvent être considérées comme des manches (et probablement plus efficace) des versions de la
IntBinaryOperator
de mise en œuvre ci-dessus!(Voir aussi La traduction des Expressions Lambda)
OriginalL'auteur isnot2bad
::
est appelée Méthode de Référence. Il s'agit d'une référence à une méthode unique. I. e. il se réfère à une méthode existante par nom.Courte Explication:
Ci-dessous est un exemple d'une référence à une méthode statique:
square
peuvent être passés tout comme les références de l'objet et déclenché en cas de besoin. En fait, il peut être facilement utilisé comme une référence à la "normale" méthodes des objets commestatic
ceux. Par exemple:Function
ci-dessus est un interface fonctionnelle. Pour comprendre pleinement::
, il est important de comprendre d'interfaces fonctionnelles ainsi. Clairement, un interface fonctionnelle est une interface avec une seule méthode abstraite.Exemples d'interfaces fonctionnelles comprennent
Runnable
,Callable
, etActionListener
.Function
ci-dessus est une interface fonctionnelle avec une seule méthode:apply
. Elle prend un argument et produit un résultat.La raison pour laquelle
::
s sont génial, c'est que:E. g. au lieu d'écrire le corps de lambda
Vous pouvez simplement faire
Au moment de l'exécution, ces deux
square
méthodes se comportent exactement de la même uns que les autres. Le bytecode peut ou peut ne pas être le même (bien que, pour le cas ci-dessus, la même bytecode généré; compiler ci-dessus et vérifier avecjavap -c
).Le seul critère à respecter est: la méthode que vous fournissez doit avoir une même signature de la méthode de la fonctionnelle de l'interface que vous utilisez comme référence d'objet.
Ci-dessous est illégal:
square
attend un argument et renvoie undouble
. Leget
méthode dans Fournisseur retourne une valeur, mais ne prenez pas un argument. Ainsi, il en résulte une erreur.Une méthode de référence se réfère à la méthode de l'interface fonctionnelle. (Comme mentionné, les interfaces fonctionnelles peut avoir qu'une seule méthode).
Quelques exemples: le
accept
méthode dans Consommateurs prend une entrée, mais ne retourne rien.Ci-dessus,
getRandom
ne prend aucun argument et renvoie undouble
. De sorte que toute interface fonctionnelle qui répond aux critères de: prendre aucun argument et retourdouble
peut être utilisé.Un autre exemple:
En cas de type paramétré:
Méthode références peuvent avoir des styles différents, mais, fondamentalement, ils signifient tous la même chose et peut simplement être visualisées sous forme de lambda:
ClassName::methName
)instanceRef::methName
)super::methName
)ClassName::methName
)ClassName::new
)TypeName[]::new
)Pour plus de renseignements, voir http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html.
Ce doit avoir été accepté de répondre.
OriginalL'auteur Jatin
Oui, c'est vrai. Le
::
opérateur est utilisé pour la méthode de référencement. Ainsi, l'on peut extraire statique méthodes de classes en utilisant des méthodes ou des objets. Le même opérateur peut être utilisé même pour les constructeurs. Tous les cas mentionnés ici sont illustrées dans l'exemple de code ci-dessous.La documentation officielle d'Oracle peut être trouvé ici.
Vous pouvez avoir une meilleure vue d'ensemble du JDK 8 changements dans cette article. Dans le Méthode ou le Constructeur de référencement section un exemple de code est également fournie:
une bonne explication est celle qui se trouve ici: doanduyhai.wordpress.com/2012/07/14/...
est l'invocation et la définition de la méthode serait comme
public static void method(IntBinaryOperator op){System.out.println(op.applyAsInt(1, 2));}
. C'est la façon dont il est utilisé.Pour ceux qui sont familiers avec le C# c'est similaire avec DelegateType d = new DelegateType(MethodName);
OriginalL'auteur Olimpiu POP
::
est un nouvel opérateur inclus dans Java 8 qui est utilisé pour se référer à une méthode d'une classe existante. Vous pouvez consulter les méthodes statiques et non statiques les méthodes d'une classe.De renvoi des méthodes statiques, la syntaxe est la suivante:
Renvoi de la non-méthodes statiques, la syntaxe est
Et
La seule condition préalable pour la référence d'une méthode est que la méthode existe dans une interface fonctionnelle, qui doit être compatible avec la méthode de référence.
Méthode des références, lors de l'évaluation, de créer une instance de l'interface fonctionnelle.
Trouvée sur: http://www.speakingcs.com/2014/08/method-references-in-java-8.html
OriginalL'auteur sreenath
Il semble que son peu en retard mais voici mes deux cents. Un expression lambda est utilisé pour créer des méthodes anonymes. Il ne fait rien, mais l'appel d'une méthode existante, mais il est plus clair de se référer à la méthode directement par son nom. Et méthode de référence nous permet de le faire à l'aide de la méthode de référence de l'opérateur
::
.Envisager les mesures suivantes simple de la classe où chaque employé a un nom et grade.
Supposons que nous avons une liste des employés renvoyés par un peu de méthode, et nous voulons trier les salariés par leur grade. Nous savons que nous pouvons faire usage de la classe anonyme comme:
où getDummyEmployee() est une méthode comme:
Maintenant, nous savons que Comparateur est une Interface Fonctionnelle. Un Interface Fonctionnelle est l'un avec exactement une méthode abstraite (même s'il peut contenir un ou plusieurs défaut ou méthodes statiques). Lambda expression permettant la mise en œuvre de
@FunctionalInterface
donc une interface fonctionnelle peut avoir qu'une seule méthode abstraite. Nous pouvons utiliser l'expression lambda comme:Il semble tout bon, mais ce que si la classe
Employee
fournit également une méthode similaire:Dans ce cas, le nom de la méthode elle-même sera plus clair. Par conséquent, nous pouvons directement référence à la méthode par l'aide de la méthode de référence comme:
Comme par docs il y a quatre types de méthode références:
OriginalL'auteur i_am_zero
C'est une référence à une méthode en Java 8. La documentation oracle est ici.
Comme indiqué dans la documentation...
Ni compareByName. De là, vous pouvez accéder à ces non-statique méthodes par le biais de l'opérateur de référence à l'aide d'un objet. Si ils étaient statiques, vous pouvez utiliser le nom de la classe comme ComparisionProvider::someStaticMethod
OriginalL'auteur david99world
:: Operator a été introduit dans java 8 pour la méthode de référence. Une méthode de référence est l'abréviation syntaxe d'une expression lambda qui s'exécute UNE seule méthode. Voici la syntaxe générale d'une méthode de référence:
Nous savons que nous pouvons utiliser les expressions lambda au lieu d'utiliser une classe anonyme. Mais parfois, l'expression lambda est vraiment juste un appel à une méthode, par exemple:
Pour rendre le code plus clair, vous pouvez transformer cette expression lambda dans une méthode de référence:
OriginalL'auteur Vaibhav9518
L' :: est connu comme la méthode de référence. Disons que nous voulons appeler un calculatePrice méthode de classe d'Achat. Ensuite, nous pouvons écrire que:
Il peut aussi être vu comme la forme courte de la rédaction de l'expression lambda Parce que la méthode références sont convertis en des expressions lambda.
OriginalL'auteur Sonu
Au moment de l'exécution, ils se conduisent exactement la même.Le bytecode peut/ne pas être la même (ci-dessus au Cas où,il génère le même code binaire(complie ci-dessus et vérifier javaap -c;))
Au moment de l'exécution, ils se conduisent exactement la même.méthode(math::max);,il génère le même pour les mathématiques (complie ci-dessus et vérifier javap -c;))
OriginalL'auteur Alfa khatoon
return reduce(Math::max);
est PAS ÉGAL àreturn reduce(max());
Mais il signifie quelque chose comme ceci:
Vous pouvez simplement enregistrer 47 frappes si vous écrivez comme ça
OriginalL'auteur Jude Niroshan
Depuis de nombreuses réponses ici bien expliqué
::
comportement, en outre, je tiens à préciser que::
opérateur n'a pas besoin d'avoir exactement la même signature que le renvoi Interface Fonctionnelle si elle est utilisée pour les variables d'instance. Supposons nous avons besoin d'un BinaryOperator qui a le type de TestObject. De façon traditionnelle son œuvre comme ceci:Comme vous le voyez anonyme, mise en œuvre, il nécessite deux TestObject argument et renvoie un TestObject objet. Pour satisfaire à cette condition en utilisant
::
opérateur, nous pouvons commencer avec une méthode statique:puis composez le:
Ok il a compilé amende. Que dire si nous avons besoin d'une méthode d'instance? Permet de mettre à jour TestObject avec la méthode d'instance:
Maintenant, nous pouvons accéder exemple comme ci-dessous:
Ce code compile bien, mais en dessous d'un pas:
Mon eclipse me dire "Ne peut pas faire une référence statique pour les non méthode statique testInstance(TestObject, TestObject) à partir du type TestObject ..."
Juste assez de son une méthode d'instance, mais si l'on surcharge
testInstance
comme ci-dessous:Et appel:
Le code juste compiler amende. Parce qu'il appellera
testInstance
avec un seul paramètre à la place de double. Ok, donc ce qui est arrivé à nos deux paramètre? Permet l'impression et à voir:Qui sera de sortie:
Ok, donc JVM est assez intelligent pour appeler param1.testInstance(param2). Peut-on utiliser
testInstance
à partir d'une autre ressource, mais pas TestObject, c'est à dire:Et appel:
Il sera tout simplement pas le compiler et de le compilateur va dire: "Le type TestUtil ne définit pas testInstance(TestObject, TestObject)". Donc le compilateur va chercher une référence statique si elle n'est pas du même type. Ok ce que sur le polymorphisme? Si on enlève la finale de modificateurs et d'ajouter notre SubTestObject classe:
Et appel:
Il ne compile pas ainsi, le compilateur va encore chercher statique de référence. Mais au-dessous de code compile très bien, puisque c'est en passant est-un test:
OriginalL'auteur HRgiger
En java-8 Flux de Réducteur dans un simple œuvres est une fonction qui prend deux valeurs en entrée et renvoie le résultat après un certain calcul. ce résultat est alimenté dans l'itération suivante.
dans le cas des Mathématiques:la fonction max, la méthode retourne un maximum de deux valeurs transmises et à la fin vous avez plus grand nombre dans la main.
OriginalL'auteur Pramod
Dans les anciennes versions de Java, au lieu de "::" ou lambd, vous pouvez utiliser:
Ou de passer à la méthode:
OriginalL'auteur Kamil Tomasz Jarmusik
Donc je vois ici des tonnes de réponses qui sont franchement trop compliqué, et c'est un euphémisme.
La réponse est assez simple: :: ça s'appelle une Méthode Références https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Donc je ne vais pas copier-coller, sur le lien, vous pouvez trouver toutes les informations si vous faites défiler vers le bas de la table.
Maintenant, nous allons jeter un bref coup d'œil à ce qui est une Méthode Références:
A::B un peu substituts suivants inline expression lambda: (params ...) -> A. B(params ...)
À corréler cela avec vos questions, il est nécessaire de comprendre un java expression lambda. Ce qui n'est pas dur.
D'insertion de l'expression lambda est similaire à un défini interface fonctionnelle (qui est une interface qui n'est ni plus ni moins que la méthode 1).
Jetons un bref coup d'œil ce que je veux dire:
InterfaceX doit être une interface fonctionnelle. Toute interface fonctionnelle, la seule chose que ce qui est important à propos de InterfaceX pour que le compilateur est que vous pouvez définir le format:
InterfaceX peut être de tout cela:
ou ce
ou plus générique:
Prenons le premier cas présenté et le inline expression lambda que nous avons définie plus haut.
Avant Java 8, vous pourriez avoir défini de la même manière cette manière:
Fonctionnellement, c'est la même chose. La différence est plus dans la façon dont le compilateur perçoit cette.
Maintenant que nous avons pris un coup d'oeil à inline expression lambda, revenons à la Méthode des Références (::). Disons que vous avez une classe comme ceci:
Depuis méthode anyFunctions a les même types que InterfaceX callMe, nous pouvons equivalate ces deux avec une Méthode de Référence.
On peut l'écrire comme ceci:
et qui est équivalent à ceci :
Une chose de cool et avantage de la Méthode Références sont qu'au début, jusqu'à ce que vous les affecter à des variables, ils sont sans type. De sorte que vous pouvez passer en paramètres à tout équivalent à la recherche (a même des types définis par l') interface fonctionnelle. Ce qui est exactement ce qui se passe dans votre cas
OriginalL'auteur Nertan Lucian
Les réponses précédentes sont tout à fait complet sur ce
::
méthode de référence n'. Pour résumer, il offre un moyen de se référer à une méthode(ou le constructeur) sans l'exécuter, et au moment de l'évaluation, il crée une instance de l'interface fonctionnelle qui fournit le type de cible contexte.Ci-dessous deux exemples de trouver un objet avec la valeur max dans un
ArrayList
AVEC et SANS l'utilisation de::
méthode de référence. Les explications sont dans les commentaires ci-dessous.SANS l'utilisation de
::
AVEC l'utilisation de
::
OriginalL'auteur Liutong Chen
J'ai trouvé cette source très intéressant.
En fait, c'est la Lambda qui se transforme en un deux points.
Les deux points est plus lisible.
Nous suivez ces étapes:
ETAPE 1:
ETAPE 2:
ETAPE 3:
Person::getAge()
devrait êtrePerson::getAge
.OriginalL'auteur Houssem Badri
Deux points à savoir :: operator est introduire dans Java 8 en tant que méthode de référence. La méthode de référence est une forme d'expression lambda qui est utilisé pour désigner la méthode existante par son nom.
classname::methodName
ex:-
En utilisant deux points ::
OriginalL'auteur ishant kulshreshtha