1
votes

référence de méthode dans java 8?

J'ai lu dans des didacticiels que lors de l'utilisation de la référence de méthode, les arguments doivent être mis en correspondance dans la méthode et la méthode de l'interface fonctionnelle auxquelles nous faisons référence. Donc je reçois l'erreur suivante.

package com;

public class Transaction {

    private int id;
    private int value;

    public Transaction(int id,int value)
    {
        this.id=id;
        this.value=value;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }


}


package com;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class MethodRefTest {

    public static void main(String[] args)
    {

        Transaction t1=new Transaction(1,20);
        Transaction t2=new Transaction(2,30);
        List<Transaction> list=new ArrayList<Transaction>();
        list.add(t1);
        list.add(t2);
        List<Integer> intList=list.stream().map(Transaction::getId).collect(Collectors.toList());
        System.out.println(intList);

    }
}

Maintenant que j'ai compris pourquoi je reçois cette erreur Regardez l'extrait de code ci-dessous

public class MethodRefTest 
{
    public static void m1(int i)
    {
        System.out.println("Hey in method 1");
    }


    public static void main(String[] args)
    {

        Runnable r=MethodRefTest::m1; //Compile time error

    }
}

Dans la méthode map que j'ai utilisée, il accepte Function FunctionalInterface ... mais la référence de méthode que j'ai utilisée n'a aucun argument, mais la méthode apply (T t) de Function a un argument, et getId () n'a aucun argument, Dans ce cas, il ne renvoie aucune erreur même si les arguments ne correspondent pas.

Veuillez m'aider à comprendre cela?


0 commentaires

3 Réponses :


0
votes

mais la méthode apply (T t) de Function a un argument, et getId () n'a aucun argument

La fonction apply prend un argument comme un type de données et renvoie un autre type de données. Dans votre cas, c'est comme si:

Consumer<Integer> consumer = MethodRefTest::m1

La Function complète dans l'opération map définit bien sûr l'entrée et le type de sortie de la transformation comme:

new Function<Transaction, Integer>() {
    @Override
    public Integer apply(Transaction transaction) {
        return transaction.getId();
    }
}

Au contraire, dans votre code m1 nécessite un argument de type entier à fournir à lui, ce qui entraînerait une sortie void . Par conséquent, votre implémentation correspond à un Consumer et peut être représenté comme:

public Integer apply(Transaction transaction) {
    return transaction.getId();
}

1 commentaires

Pour vraiment créer un Runnable , fournissez-lui une entrée comme Runnable r = () -> m1 (2); // en remplaçant 2 par une valeur entière



0
votes

La référence de méthode

(Transaction t) -> t.getId()

est égale à expression lambda

Transaction::getId

Ce que vous pouvez voir accepter un argument Transaction et renvoyer une valeur int

C'est une Function code> signature, car il remplit pleinement ses conditions.


0 commentaires

0
votes

Le compilateur Java est autorisé à faire correspondre une référence de méthode à une méthode non statique avec n - 1 arguments comme si elle correspondait, avec l'objet lui-même comme premier argument. La section du JLS est 15.13.1 :

Sinon, étant donné un type de fonction ciblée avec les types de paramètres P 1 , ..., P n et un ensemble de méthodes potentiellement applicables, la déclaration à la compilation est sélectionné comme suit:

  • Si l'expression de référence de méthode a la forme ReferenceType :: [TypeArguments] Identifier , alors deux recherches pour une méthode applicable la plus spécifique sont effectuées. Chaque recherche est telle que spécifiée aux §15.12.2.2 à §15.12.2.5, avec les précisions ci-dessous. Chaque recherche produit un ensemble de méthodes applicables et, éventuellement, désigne une méthode la plus spécifique de l'ensemble. En cas d'erreur comme spécifié au §15.12.2.4, l'ensemble des méthodes applicables est vide. Dans le cas d'une erreur comme spécifié au §15.12.2.5, il n'y a pas de méthode la plus spécifique.

    Lors de la première recherche, la référence de méthode est traitée comme s'il s'agissait d'un appel avec des expressions d'argument de types P 1 , ..., P n . Les arguments de type, le cas échéant, sont donnés par l'expression de référence de méthode.

    Dans la deuxième recherche, si P 1 , ..., P n n'est pas vide et P 1 est un sous-type de < em> ReferenceType , alors l'expression de référence de méthode est traitée comme s'il s'agissait d'une expression d'invocation de méthode avec des expressions d'argument de types P 2 , ..., P n .

    Si la première recherche produit une méthode plus spécifique qui est statique et que l'ensemble des méthodes applicables produit par la deuxième recherche ne contient aucune méthode non statique , alors le La déclaration à la compilation est la méthode la plus spécifiée de la première recherche.

    Sinon, si l'ensemble des méthodes applicables produit par la première recherche ne contient aucune méthode statique et que la deuxième recherche produit une méthode plus spécifique qui n'est pas statique , alors la déclaration à la compilation est la méthode la plus spécifique de la deuxième recherche.

La "première recherche" est la correspondance directe des paramètres de méthode avec un type d'interface fonctionnelle. La "deuxième recherche" ajoute une certaine flexibilité en ce que l'instance d'objet elle-même à partir d'une référence de méthode peut servir de premier paramètre correspondant à une interface fonctionnelle.

Dans votre exemple principal, la méthode m1 est statique et aucune instance ne peut être implicitement le premier argument, donc la "deuxième recherche" ne s'applique pas ici.

Dans l'exemple du bas, le getId n'est pas statique, et la "deuxième recherche" ci-dessus s'applique. Ici, getId n'a pas d'arguments, donc l'ensemble de paramètres "P2-Pn" est vide. Cependant, l'objet lui-même est le premier argument implicite, il correspond donc à la signature fonctionnelle Function attendue par la méthode map dans Stream .


0 commentaires