web-dev-qa-db-fra.com

:: opérateur double virgule en Java 8

J'explorais le code source Java 8 et trouvais cette partie du code très surprenante:

//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;
}

Math::max ressemble-t-il à un pointeur de méthode? Comment une méthode static normale est-elle convertie en IntBinaryOperator?

829
Narendra Pathai

Habituellement, on appelle la méthode reduce en utilisant Math.max(int, int) comme suit:

reduce(new IntBinaryOperator() {
    int applyAsInt(int left, int right) {
        return Math.max(left, right);
    }
});

Cela nécessite beaucoup de syntaxe pour appeler Math.max. C'est là que les expressions lambda entrent en jeu. Depuis Java 8, il est permis de faire la même chose de manière beaucoup plus courte:

reduce((int left, int right) -> Math.max(left, right));

Comment cela marche-t-il? Le compilateur Java "détecte" le fait que vous souhaitez implémenter une méthode qui accepte deux ints et renvoie un int. Cela équivaut aux paramètres formels de l'unique méthode d'interface IntBinaryOperator (paramètre de la méthode reduce que vous souhaitez appeler). Ainsi, le compilateur fait le reste pour vous - il suppose simplement que vous souhaitiez implémenter IntBinaryOperator.

Toutefois, étant donné que Math.max(int, int) remplit lui-même les conditions de forme de IntBinaryOperator, il peut être utilisé directement. Java 7 ne disposant d'aucune syntaxe permettant de transmettre une méthode en tant qu'argument (vous pouvez uniquement transmettre les résultats de méthode, mais jamais les références de méthode), la syntaxe :: a été introduite dans Java 8 pour référencer les méthodes:

reduce(Math::max);

Notez que cela sera interprété par le compilateur, pas par la JVM lors de l'exécution! Bien qu'il produise des codes octets différents pour les trois extraits de code, ils sont sémantiquement égaux. Les deux derniers peuvent donc être considérés comme des versions courtes (et probablement plus efficaces) de l'implémentation IntBinaryOperator ci-dessus!

(Voir aussi Traduction des expressions lambda )

915
isnot2bad

:: est appelé référence de méthode. C'est fondamentalement une référence à une seule méthode. C'est à dire. il fait référence à une méthode existante par son nom.

Explication courte:
Voici un exemple de référence à une méthode statique:

class Hey {
     public static double square(double num){
        return Math.pow(num, 2);
    }
}

Function<Double, Double> square = Hey::square;
double ans = square.apply(23d);

square peut être passé comme les références d'objet et déclenché si nécessaire. En fait, il peut être utilisé aussi facilement comme référence aux méthodes "normales" d’objets que les méthodes static. Par exemple:

class Hey {
    public double square(double num) {
        return Math.pow(num, 2);
    }
}

Hey hey = new Hey();
Function<Double, Double> square = hey::square;
double ans = square.apply(23d);

Function ci-dessus est une interface fonctionnelle. Pour bien comprendre ::, il est également important de comprendre les interfaces fonctionnelles. En clair, une interface fonctionnelle est une interface avec une seule méthode abstraite.

Des exemples d'interfaces fonctionnelles incluent Runnable, Callable et ActionListener.

Function ci-dessus est une interface fonctionnelle avec une seule méthode: apply. Cela prend un argument et produit un résultat.


La raison pour laquelle ::s sont géniaux est that :

Les références de méthode sont des expressions qui ont le même traitement que les expressions lambda (...), mais au lieu de fournir un corps de méthode, elles référencent une méthode existante par son nom.

Par exemple. au lieu d'écrire le corps lambda

Function<Double, Double> square = (Double x) -> x * x;

Vous pouvez simplement faire

Function<Double, Double> square = Hey::square;

Au moment de l'exécution, ces deux méthodes square se comportent exactement de la même manière. Le pseudo-code peut être différent ou non (cependant, dans le cas ci-dessus, le même pseudo est généré; compilez ce qui précède et vérifiez avec javap -c).

Le seul critère important à satisfaire est: la méthode que vous fournissez doit avoir une signature similaire à la méthode de l'interface fonctionnelle que vous utilisez comme référence d'objet}.

Le ci-dessous est illégal:

Supplier<Boolean> p = Hey::square; // illegal

square attend un argument et retourne une double. La méthode get dans Supplier renvoie une valeur mais ne prend pas d'argument. Cela entraîne donc une erreur. 

Une référence de méthode fait référence à la méthode d'une interface fonctionnelle. (Comme mentionné, les interfaces fonctionnelles ne peuvent avoir qu'une méthode chacune). 

Quelques exemples supplémentaires: la méthode accept dans Consumer prend une entrée mais ne retourne rien.

Consumer<Integer> b1 = System::exit;   // void exit(int status)
Consumer<String[]> b2 = Arrays::sort;  // void sort(Object[] a)
Consumer<String> b3 = MyProgram::main; // void main(String... args)

class Hey {
    public double getRandom() {
        return Math.random();
    }
}

Callable<Double> call = hey::getRandom;
Supplier<Double> call2 = hey::getRandom;
DoubleSupplier sup = hey::getRandom;
// Supplier is functional interface that takes no argument and gives a result

Ci-dessus, getRandom ne prend aucun argument et retourne un double. Ainsi, toute interface fonctionnelle qui satisfait les critères de: ne prend aucun argument et renvoie double peut être utilisée. 

Un autre exemple:

Set<String> set = new HashSet<>();
set.addAll(Arrays.asList("leo","bale","hanks"));
Predicate<String> pred = set::contains;
boolean exists = pred.test("leo");

En cas de types paramétrés:

class Param<T> {
    T elem;
    public T get() {
        return elem;
    }

    public void set(T elem) {
        this.elem = elem;
    }

    public static <E> E returnSame(E elem) {
        return elem;
    }
}

Supplier<Param<Integer>> obj = Param<Integer>::new;
Param<Integer> param = obj.get();
Consumer<Integer> c = param::set;
Supplier<Integer> s = param::get;

Function<String, String> func = Param::<String>returnSame;

Les références de méthode peuvent avoir différents styles, mais fondamentalement, elles signifient toutes la même chose et peuvent simplement être visualisées sous la forme de lambdas:

  1. Une méthode statique (ClassName::methName)
  2. Une méthode d'instance d'un objet particulier (instanceRef::methName)
  3. Une super méthode d'un objet particulier (super::methName)
  4. Une méthode d'instance d'un objet arbitraire d'un type particulier (ClassName::methName)
  5. Une référence de constructeur de classe (ClassName::new)
  6. Une référence de constructeur de tableau (TypeName[]::new)

Pour plus de détails, voir http://cr.openjdk.Java.net/~briangoetz/lambda/lambda-state-final.html .

426
Jatin

Oui c'est vrai. L'opérateur :: est utilisé pour le référencement de méthodes. Ainsi, on peut extraire les méthodes static des classes en les utilisant ou des méthodes à partir d’objets. Le même opérateur peut être utilisé même pour les constructeurs. Tous les cas mentionnés ici sont illustrés dans l'exemple de code ci-dessous.

La documentation officielle d’Oracle peut être trouvée ici .

Vous pouvez avoir une meilleure vue d'ensemble des modifications de JDK 8 dans this article. Dans la section Method/Constructor qui fait référence à, un exemple de code est également fourni:

interface ConstructorReference {
    T constructor();
}

interface  MethodReference {
   void anotherMethod(String input);
}

public class ConstructorClass {
    String value;

   public ConstructorClass() {
       value = "default";
   }

   public static void method(String input) {
      System.out.println(input);
   }

   public void nextMethod(String input) {
       // operations
   }

   public static void main(String... args) {
       // constructor reference
       ConstructorReference reference = ConstructorClass::new;
       ConstructorClass cc = reference.constructor();

       // static method reference
       MethodReference mr = cc::method;

       // object method reference
       MethodReference mr2 = cc::nextMethod;

       System.out.println(cc.value);
   }
}
50
Olimpiu POP

:: est un nouvel opérateur inclus dans Java 8 utilisé pour faire référence à une méthode d'une classe existante. Vous pouvez faire référence à des méthodes statiques et à des méthodes non statiques d'une classe.

Pour faire référence à des méthodes statiques, la syntaxe est la suivante:

ClassName :: methodName 

Pour faire référence à des méthodes non statiques, la syntaxe est la suivante:

objRef :: methodName

Et

ClassName :: methodName

La seule condition préalable pour faire référence à une méthode est que cette méthode existe dans une interface fonctionnelle, laquelle doit être compatible avec la référence de la méthode. 

Les références de méthode, lorsqu'elles sont évaluées, créent une instance de l'interface fonctionnelle. 

Trouvé sur: http://www.speakingcs.com/2014/08/method-references-in-Java-8.html

24
sreenath

C’est une référence de méthode en Java 8. La documentation Oracle est ici .

Comme indiqué dans la documentation ...

La référence de méthode Person :: compareByAge est une référence à un statique méthode.

Voici un exemple de référence à une méthode d'instance d'un objet particulier:

class ComparisonProvider {
    public int compareByName(Person a, Person b) {
        return a.getName().compareTo(b.getName());
    }

    public int compareByAge(Person a, Person b) {
        return a.getBirthday().compareTo(b.getBirthday());
    }
}

ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName); 

La référence à la méthode myComparisonProvider :: compareByName appelle la méthode compareByName cela fait partie de l'objet myComparisonProvider. La JRE en déduit le arguments de type de méthode, qui dans ce cas sont (Personne, Personne).

19
david99world

Il semble que ce soit un peu tard, mais voici mes deux sous. Une expression lambda est utilisée pour créer des méthodes anonymes. Il ne fait rien qu'appeler une méthode existante, mais il est plus clair de se référer à la méthode directement par son nom. Et method reference nous permet de le faire en utilisant l'opérateur de référence de méthode ::.

Considérez la classe simple suivante où chaque employé a un nom et un grade.

public class Employee {
    private String name;
    private String grade;

    public Employee(String name, String grade) {
        this.name = name;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }
}

Supposons que nous ayons une liste d'employés renvoyés par une méthode quelconque et que nous voulions trier les employés par leur grade. Nous savons que nous pouvons utiliser la classe anonymous comme:

    List<Employee> employeeList = getDummyEmployees();

    // Using anonymous class
    employeeList.sort(new Comparator<Employee>() {
           @Override
           public int compare(Employee e1, Employee e2) {
               return e1.getGrade().compareTo(e2.getGrade());
           }
    });

où getDummyEmployee () est une méthode comme: 

private static List<Employee> getDummyEmployees() {
        return Arrays.asList(new Employee("Carrie", "C"),
                new Employee("Farhan", "F"),
                new Employee("Brian", "B"),
                new Employee("Donald", "D"),
                new Employee("Adam", "A"),
                new Employee("Evan", "E")
                );
    }

Nous savons maintenant que Comparator est une interface fonctionnelle. Un Functional Interface est celui avec exactement une méthode abstraite (bien qu'il puisse contenir une ou plusieurs méthodes par défaut ou statiques). L'expression Lambda fournit l'implémentation de @FunctionalInterface afin qu'une interface fonctionnelle ne puisse avoir qu'une seule méthode abstraite. Nous pouvons utiliser l'expression lambda comme:

employeeList.sort((e1,e2) -> e1.getGrade().compareTo(e2.getGrade())); // lambda exp

Cela semble bien, mais que se passe-t-il si la classe Employee fournit également une méthode similaire:

public class Employee {
    private String name;
    private String grade;
    // getter and setter
    public static int compareByGrade(Employee e1, Employee e2) {
        return e1.grade.compareTo(e2.grade);
    }
}

Dans ce cas, l'utilisation du nom de la méthode elle-même sera plus claire. Par conséquent, nous pouvons nous référer directement à la méthode en utilisant la référence de méthode comme

employeeList.sort(Employee::compareByGrade); // method reference

Selon docs , il existe quatre types de références de méthodes:

+----+-------------------------------------------------------+--------------------------------------+
|    | Kind                                                  | Example                              |
+----+-------------------------------------------------------+--------------------------------------+
| 1  | Reference to a static method                          | ContainingClass::staticMethodName    |
+----+-------------------------------------------------------+--------------------------------------+
| 2  |Reference to an instance method of a particular object | containingObject::instanceMethodName | 
+----+-------------------------------------------------------+--------------------------------------+
| 3  | Reference to an instance method of an arbitrary object| ContainingType::methodName           |
|    | of a particular type                                  |                                      |  
+----+-------------------------------------------------------+--------------------------------------+
| 4  |Reference to a constructor                             | ClassName::new                       |
+------------------------------------------------------------+--------------------------------------+
18
i_am_zero

:: Operator a été introduit dans Java 8 pour les références de méthodes. Une référence de méthode est la syntaxe abrégée d'une expression lambda qui exécute une seule méthode. Voici la syntaxe générale d'une référence de méthode:

Object :: methodName

Nous savons que nous pouvons utiliser expressions lambda au lieu d'utiliser une classe anonyme. Mais parfois, l'expression lambda n'est en réalité qu'un appel à une méthode, par exemple:

Consumer<String> c = s -> System.out.println(s);

Pour rendre le code plus clair, vous pouvez transformer cette expression lambda en une référence de méthode:

Consumer<String> c = System.out::println;
4
Vaibhav9518

Le :: est connu sous le nom de référence de méthode. Disons que nous voulons appeler une méthode CalculatePrice de la classe Purchase. Ensuite, nous pouvons l'écrire comme:

Purchase::calculatePrice

Cela peut également être vu comme une forme abrégée d'écriture de l'expression lambda, car les références de méthode sont converties en expressions lambda.

3
Sonu

Au moment de l'exécution, ils se comportent exactement de la même manière. Le code intermédiaire peut ne pas être identique (pour Incase ci-dessus, il génère le même code secondaire (conforme ci-dessus et vérifiez javaap -c;))

Au moment de l'exécution, ils se comportent exactement de la même manière.method (math :: max) ;, il génère le même calcul (conforme ci-dessus et vérifiez javap -c;))

2
Alfa khatoon

return reduce(Math::max); est NOT EQUAL to return reduce(max());

Mais cela signifie quelque chose comme ceci:

IntBinaryOperator myLambda = (a, b)->{(a >= b) ? a : b};//56 keystrokes I had to type -_-
return reduce(myLambda);

Vous pouvez simplement enregistrer 47 séquences de touches si vous écrivez comme ceci

return reduce(Math::max);//Only 9 keystrokes ^_^
2
Jude Niroshan

Dans Java-8 Streams Reducer, dans les travaux simples, est une fonction qui prend deux valeurs en entrée et renvoie le résultat après un calcul. ce résultat est alimenté à la prochaine itération.

dans le cas de Math: fonction max, la méthode renvoie en permanence le maximum de deux valeurs passées et à la fin vous avez le plus grand nombre en main.

2
Pramod

Dans les anciennes versions de Java, au lieu de "::" ou de lambd, vous pouvez utiliser:

public interface Action {
    void execute();
}

public class ActionImpl implements Action {

    @Override
    public void execute() {
        System.out.println("execute with ActionImpl");
    }

}

public static void main(String[] args) {
    Action action = new Action() {
        @Override
        public void execute() {
            System.out.println("execute with anonymous class");
        }
    };
    action.execute();

    //or

    Action actionImpl = new ActionImpl();
    actionImpl.execute();
}

Ou en passant à la méthode:

public static void doSomething(Action action) {
    action.execute();
}
1

Les réponses précédentes sont assez complètes sur ce que fait la référence à la méthode ::. En résumé, il fournit un moyen de faire référence à une méthode (ou à un constructeur) sans l'exécuter et, une fois évalué, il crée une instance de l'interface fonctionnelle qui fournit le contexte de type cible.

Vous trouverez ci-dessous deux exemples pour rechercher un objet avec la valeur maximale dans une variable ArrayList WITH et WITHOUT avec la référence à la méthode ::. Les explications sont dans les commentaires ci-dessous.


SANS utilisation de ::

import Java.util.*;

class MyClass {
    private int val;
    MyClass (int v) { val = v; }
    int getVal() { return val; }
}

class ByVal implements Comparator<MyClass> {
    // no need to create this class when using method reference
    public int compare(MyClass source, MyClass ref) {
        return source.getVal() - ref.getVal();
    }
}

public class FindMaxInCol {
    public static void main(String args[]) {
        ArrayList<MyClass> myClassList = new ArrayList<MyClass>();
        myClassList.add(new MyClass(1));
        myClassList.add(new MyClass(0));
        myClassList.add(new MyClass(3));
        myClassList.add(new MyClass(6));

        MyClass maxValObj = Collections.max(myClassList, new ByVal());
    }
}

AVEC l'utilisation de ::

import Java.util.*;

class MyClass {
    private int val;
    MyClass (int v) { val = v; }
    int getVal() { return val; }
}

public class FindMaxInCol {
    static int compareMyClass(MyClass source, MyClass ref) {
        // This static method is compatible with the compare() method defined by Comparator. 
        // So there's no need to explicitly implement and create an instance of Comparator like the first example.
        return source.getVal() - ref.getVal();
    }

    public static void main(String args[]) {
        ArrayList<MyClass> myClassList = new ArrayList<MyClass>();
        myClassList.add(new MyClass(1));
        myClassList.add(new MyClass(0));
        myClassList.add(new MyClass(3));
        myClassList.add(new MyClass(6));

        MyClass maxValObj = Collections.max(myClassList, FindMaxInCol::compareMyClass);
    }
}
1
Liutong Chen

Donc je vois ici des tonnes de réponses franchement trop compliquées, et c'est un euphémisme. 

La réponse est assez simple: :: c'est ce qu'on appelle une méthode Référenceshttps://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 jusqu'à la table.


Maintenant, jetons un coup d’œil à ce qu’est une référence de méthode:

A :: B _ ​​un peu remplace le expression lambda en ligne} suivant: _ ((params ...) -> A.B (params ...)

Pour corréler cela avec vos questions, il est nécessaire de comprendre une expression Java lambda. Ce qui n'est pas difficile.

Une expression lambda en ligne est similaire à une interface fonctionnelle définie(c'est-à-dire une interface qui ne comporte pas plus ni moins d'une méthode). Voyons ce que je veux dire:

InterfaceX f = (x) -> x*x; 

InterfaceX doit être une interface fonctionnelle. Quelle que soit l'interface fonctionnelle, le seul élément important d'InterfaceX pour ce compilateur est de définir le format:

InterfaceX peut être n'importe lequel:

interface InterfaceX
{
    public Integer callMe(Integer x);
}

ou ca

interface InterfaceX
{
    public Double callMe(Integer x);
}

ou plus générique:

interface InterfaceX<T,U>
{
    public T callMe(U x);
}

Prenons le premier cas présenté et l'expression en ligne lambda que nous avons définie précédemment. 

Avant Java 8, vous auriez pu le définir de la manière suivante:

 InterfaceX o = new InterfaceX(){
                     public int callMe (int x, int y) 
                       {
                        return x*x;
                       } };

Fonctionnellement, c'est la même chose. La différence réside davantage dans la façon dont le compilateur perçoit cela. 

Maintenant que nous avons jeté un coup d'œil à l'expression lambda intégrée, revenons à la méthode Method References (: :). Disons que vous avez un cours comme celui-ci:

class Q {
        public static int anyFunction(int x)
             {
                 return x+5;
             } 
        }

Comme la méthode anyFunctions a les mêmes types que InterfaceX callMe, nous pouvons assimiler ces deux méthodes à une référence de méthode.

Nous pouvons l'écrire comme ceci:

InterfaceX o =  Q::anyFunction; 

et cela équivaut à ceci:

InterfaceX o = (x) -> Q.anyFunction(x);

Un avantage et un avantage des références de méthode sont qu’au début, jusqu’à ce que vous les affectiez à des variables, elles sont sans type. Vous pouvez donc les transmettre en tant que paramètres à n’importe quelle interface fonctionnelle de recherche équivalente (ayant les mêmes types définis). Quel est exactement ce qui se passe dans votre cas

1
Nertan Lucian

Étant donné que de nombreuses réponses ici expliquent bien le comportement de ::, j'aimerais également préciser que ::operator n'a pas besoin d'avoir exactement la même signature que l'interface fonctionnelle de référence si elle est utilisée pour les variables d'instance. Supposons que nous ayons besoin de BinaryOperator qui a le type de TestObject. De manière traditionnelle, son implémentation est la suivante:

BinaryOperator<TestObject> binary = new BinaryOperator<TestObject>() {

        @Override
        public TestObject apply(TestObject t, TestObject u) {

            return t;
        }
    };

Comme vous le voyez dans l'implémentation anonyme, il nécessite deux arguments TestObject et renvoie également un objet TestObject. Pour satisfaire cette condition en utilisant l'opérateur ::, nous pouvons commencer par une méthode statique:

public class TestObject {


    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

puis appelez:

BinaryOperator<TestObject> binary = TestObject::testStatic;

Ok, c'est bien compilé. Qu'en est-il si nous avons besoin d'une méthode d'instance? Permet de mettre à jour TestObject avec la méthode d'instance:

public class TestObject {

    public final TestObject testInstance(TestObject t, TestObject t2){
        return t;
    }

    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

Nous pouvons maintenant accéder à l'instance ci-dessous:

TestObject testObject = new TestObject();
BinaryOperator<TestObject> binary = testObject::testInstance;

Ce code compile bien, mais en dessous de l'un pas:

BinaryOperator<TestObject> binary = TestObject::testInstance;

Mon Eclipse me dit "Impossible de faire une référence statique à la méthode non statique testInstance (TestObject, TestObject) à partir du type TestObject ..."

Assez bien, c’est une méthode d’instance, mais si nous surchargeons testInstance comme ci-dessous:

public class TestObject {

    public final TestObject testInstance(TestObject t){
        return t;
    }

    public final TestObject testInstance(TestObject t, TestObject t2){
        return t;
    }

    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

Et appelez:

BinaryOperator<TestObject> binary = TestObject::testInstance;

Le code va juste compiler bien. Parce qu'il appellera testInstance avec un paramètre unique au lieu de double. Ok alors que sont devenus nos deux paramètres? Permet d'imprimer et de voir:

public class TestObject {

    public TestObject() {
        System.out.println(this.hashCode());
    }

    public final TestObject testInstance(TestObject t){
        System.out.println("Test instance called. this.hashCode:" 
    + this.hashCode());
        System.out.println("Given parameter hashCode:" + t.hashCode());
        return t;
    }

    public final TestObject testInstance(TestObject t, TestObject t2){
        return t;
    }

    public static final TestObject testStatic(TestObject t, TestObject t2){
        return t;
    }
}

Quel sera le résultat:

 1418481495  
 303563356  
 Test instance called. this.hashCode:1418481495
 Given parameter hashCode:303563356

Ok, la machine virtuelle Java est assez intelligente pour appeler param1.testInstance (param2). Pouvons-nous utiliser testInstance à partir d'une autre ressource mais pas de TestObject, c'est-à-dire:

public class TestUtil {

    public final TestObject testInstance(TestObject t){
        return t;
    }
}

Et appelez:

BinaryOperator<TestObject> binary = TestUtil::testInstance;

Il ne sera tout simplement pas compilé et le compilateur dira: "Le type TestUtil ne définit pas testInstance (TestObject, TestObject)". Donc, le compilateur cherchera une référence statique si ce n'est pas le même type. Ok Qu'en est-il du polymorphisme? Si nous supprimons les modificateurs finaux et ajoutons notre classe SubTestObject:

public class SubTestObject extends TestObject {

    public final TestObject testInstance(TestObject t){
        return t;
    }

}

Et appelez:

BinaryOperator<TestObject> binary = SubTestObject::testInstance;

Il ne compilera pas non plus, le compilateur recherchera toujours une référence statique. Mais le code ci-dessous compilera bien puisqu'il passe est un test:

public class TestObject {

    public SubTestObject testInstance(Object t){
        return (SubTestObject) t;
    }

}

BinaryOperator<TestObject> binary = TestObject::testInstance;

* Je suis juste en train d'étudier, j'ai donc découvert en essayant de voir, n'hésitez pas à me corriger si je me trompe

1
HRgiger

J'ai trouvé cette source très intéressant.

En fait, c’est le Lambda qui se transforme en Double Colon . Le Double Colon est plus lisible .

ÉTAPE 1:

// We create a comparator of two persons
Comparator c = (Person p1, Person p2) -> p1.getAge().compareTo(p2.getAge());

ÉTAPE 2:

// We use the interference
Comparator c = (p1, p2) -> p1.getAge().compareTo(p2.getAge());

ÉTAPE 3:

// The magic
Comparator c = Comparator.comparing(Person::getAge());
1
Husam Bdr

Les deux points doubles i.e.: l'opérateur est introduit dans Java 8 en tant que référence de méthode. La référence à la méthode est une forme d'expression lambda utilisée pour désigner la méthode existante par son nom.

classname :: methodName

ex:-

  • stream.forEach (element -> System.out.println (element))

En utilisant Double Colon ::

  • stream.forEach (System.out :: println (element))
0
ishant kulshreshtha