Le code ci-dessous fonctionne
Function fun1= Object::equals Function fun2= super::hashCode
Mais le code ci-dessous n'est pas
Function fun1= super::equals Function fun2= Object::hashCode
Quel est le concept ici même si toutes sont des méthodes d'instance dans Object classe.
J'ai lu quelque part les principaux sont:
5 Réponses :
L'interface Function
est une interface fonctionnelle représentant une fonction qui accepte un paramètre et renvoie une valeur.
super :: equals
fonctionne car c'est une fonction qui accepte un paramètre et renvoie une valeur.
Object :: equals
ne fonctionne pas car il s'agit d'une fonction qui accepte les paramètres deux et renvoie une valeur.
Si vous avez une référence de méthode de la forme ClassName :: instanceMethod
, la fonction qu'elle représente aura un paramètre supplémentaire - l'objet sur lequel appeler la méthode. Selon la documentation :
L'expression lambda équivalente pour la référence de méthode
String :: compareToIgnoreCase
aurait la liste de paramètres formels(String a, String b)
, oùa code> et
b
sont des noms arbitraires utilisés pour mieux décrire cet exemple. La référence de méthode invoquerait la méthodea.compareToIgnoreCase(b)
super :: equals
est de la forme instance :: instanceMethod
donc il n'y a pas de problème et fonctionne comme prévu.
Le type d'interface fonctionnelle correct à utiliser pour Object :: equals
et super :: hashCode
est BiFunction
et IntSupplier
.
De plus, n'utilisez pas de types bruts.
Si Object :: equals attend 2 paramètres et à cause de cela il ne fonctionne pas, alors pourquoi Object :: hashCode fonctionne il n'attend aucun paramètre I
@Balrajgoud Parce que Function
n'attend qu'un seul paramètre.
Dois-je bien comprendre que Function fun2 = Object :: hashCode;
compile, car il prend les instances actuelles comme partie argument de la fonction, mais ne le transmet pas à hashCode code> et appelle à la place cette méthode sur l'instance?
@Tom Oui, consultez la documentation citée.
@Tom oui, cette instance n'est pas passée en paramètre mais utilisée comme instance à laquelle la méthode est appliquée.
Wow, je n'ai jamais réalisé ça. Merci pour l'explication.
@Balrajgoud Êtes-vous toujours assez confus à ce sujet? Si oui, dites-le moi. Sinon, pensez à accepter la réponse.
hashCode n'est pas une fonction. c'est un fournisseur.
Supplier fun2 = super::hashCode;
hashCode
n'est pas une méthode! Vous êtes sûr??
@CommonMan 'hashCode' n'est pas une méthode? Qu'est-ce que tu racontes?
Object.hashCode (); c'est quoi?
J'ai manqué le sarcasme dans votre commentaire. Je n'ai pas vu l'erreur sur laquelle vous commentiez. Mais techniquement, il a raison. hashCode est une méthode, pas une fonction, et il a affirmé que hashCode n'est pas une fonction :)
java.util.Function
est une fonction qui prend un argument.
super :: equals
est une fonction qui prend un argument (l'objet qui est super
comparé à), donc cela fonctionne. Object :: equals
est une fonction qui prend deux arguments: l'objet cible et l'objet à comparer, donc cela ne fonctionne pas.
De même, Object :: hashCode
est une fonction d'un argument, mais super :: hashCode
est une fonction de zéro arguments.
/ p>
Très bien, je pense que ce que vous essayez également de souligner, c'est la représentation utilisant une référence de méthode, auquel cas vous avez raison.
Lorsque vous écrivez super :: methodName
, vous créez une référence de méthode sur une instance spécifique d'une classe. Par conséquent, la méthode de l'interface fonctionnelle (à laquelle vous attribuez cette référence de méthode) doit attendre le même nombre de paramètres que methodName
.
Lorsque vous écrivez ClassName :: methodName code>, si
methodName
n'est pas une méthode statique, vous créez une référence de méthode sur une instance arbitraire d'une classe. Par conséquent, la méthode de l'interface fonctionnelle (à laquelle vous attribuez cette référence de méthode) doit attendre le même nombre de paramètres que methodName
a + 1 (le paramètre supplémentaire étant l'instance de ClassName sur laquelle la méthode sera être exécutée).
Function
prend un argument et renvoie une valeur.
Par conséquent, vous pouvez lui attribuer une référence de méthode d'une instance spécifique et une seule méthode d'argument (comme dans super :: equals
) ou une référence de méthode d'une instance arbitraire et une méthode d'argument 0 (comme dans Object :: hashCode
).
Vous ne pouvez cependant pas lui attribuer une référence de méthode d'une instance arbitraire et une méthode à un seul argument (comme dans Object :: equals
), car cela nécessite deux arguments, et La fonction
n'en attend qu'un seul.
Étant donné que deux arguments sont attendus, vous pouvez attribuer cette référence de méthode à une BiFunction
:
Supplier<Integer> sup = super::hashCode;
Amélioration mineure, au lieu de Supplier
on pourrait utiliser IntSupplier
, mais sinon, bonne explication, comme toujours;) +1
@Lino eh bien, IntSupplier
et Supplier
conviennent dans ce cas.
Pour résumer, les références des méthodes sont les suivantes:
super :: equals
équivaut à Function
. Object :: hashCode
équivaut à Function
. super :: hashCode
équivaut à Supplier f = () -> super.hashCode ()
Object :: equals
équivaut à BiFunction
. li>
Notez que votre type de variable est incompatible avec la signature lambda.
Pouvez-vous développer sur "Ne fonctionne pas"?
Une chose que vous avez clairement manquée ici (dans les concepts) est le type. Vous utilisez des types bruts.
J'obtiens une erreur du compilateur disant que "le type Object ne définit pas hashCode (Object) qui est applicable ici.
Eh bien, vous avez utilisé
super
ici. Pourriez-vous s'il vous plaît modifier la question pour partager plus de détails sur la classe parent et le contexte autour du code que vous avez partagé.Veuillez lire "Comment créer un exemple reproductible minimal ". Utilisez ensuite le lien modifier pour améliorer votre question (n'ajoutez pas d'informations via les commentaires). Sinon, nous ne sommes pas en mesure de répondre à votre question et de vous aider. Ne mettez pas plus d'informations dans les commentaires, modifiez la question à la place.