5
votes

pourquoi l'opérateur Java 8 :: ne fonctionne pas pour la méthode de hashcode d'objet lorsque nous utilisons super?

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:

  1. object :: méthodes d'instance
  2. Classe :: méthode statique
  3. Méthode Class :: instance


5 commentaires

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.


5 Réponses :


11
votes

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 et b sont des noms arbitraires utilisés pour mieux décrire cet exemple. La référence de méthode invoquerait la méthode a.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.


7 commentaires

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 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.



0
votes

hashCode n'est pas une fonction. c'est un fournisseur.

Supplier fun2 = super::hashCode;


4 commentaires

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 :)



3
votes

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>


1 commentaires

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.



3
votes

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;


2 commentaires

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.



0
votes

Pour résumer, les références des méthodes sont les suivantes:

  • super :: equals équivaut à Function f = a -> super.equals (a) .
  • Object :: hashCode équivaut à Function f = a-> Object.hashCode (a) .
  • super :: hashCode équivaut à Supplier f = () -> super.hashCode ()
  • Object :: equals équivaut à BiFunction f = (a, b) -> a.equals (b) .

Notez que votre type de variable est incompatible avec la signature lambda.


0 commentaires