Y a-t-il une bonne raison pour laquelle il n'y Pair<L,R>
en a pas en Java? Quel serait l'équivalent de cette construction C ++? Je préfère éviter de réimplémenter le mien.
Il semble que 1.6 fournit quelque chose de similaire ( AbstractMap.SimpleEntry<K,V>
), mais cela semble assez compliqué.
AbstractMap.SimpleEntry
alambiqué?Réponses:
Dans un fil de discussion
comp.lang.java.help
, Hunter Gratzner donne quelques arguments contre la présence d'unePair
construction en Java. L'argument principal est qu'une classePair
ne transmet aucune sémantique sur la relation entre les deux valeurs (comment savez-vous ce que "premier" et "deuxième" signifient?).Une meilleure pratique consiste à écrire une classe très simple, comme celle proposée par Mike, pour chaque application que vous auriez faite de la
Pair
classe.Map.Entry
est un exemple d'une paire qui porte sa signification dans son nom.Pour résumer, à mon avis, il vaut mieux avoir une classe
Position(x,y)
, une classeRange(begin,end)
et une classeEntry(key,value)
plutôt qu'un génériquePair(first,second)
qui ne me dit rien de ce qu'il est censé faire.la source
C'est Java. Vous devez créer votre propre classe Pair personnalisée avec des noms de classe et de champ descriptifs, sans oublier que vous réinventerez la roue en écrivant hashCode () / equals () ou en implémentant Comparable encore et encore.
la source
SimpleImmutableEntry
Classe de paire compatible HashMap:
la source
super()
sortez. Normalement, je le couperais si c'est facultatif, comme ici.La paire la plus courte que j'ai pu trouver est la suivante, en utilisant Lombok :
Il a tous les avantages de la réponse de @arturh (sauf la comparabilité), il a
hashCode
,equals
,toString
et un statique « constructeur ».la source
Apache Commons Lang 3.0+ a quelques classes Pair: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
la source
Une autre façon d'implémenter Pair with.
Usine simple pour que vous n'ayez pas à fournir les types. par exemple Pair.of ("bonjour", 1);
la source
of
. Cela rappelle les collections immuables de Google Guava .o1
àComparable
, même si rien ne l' indique appliquera effectivement cette interface. Si c'est une exigence, leFIRST
paramètre type devrait l'êtreFIRST extends Comparable<?>
.Que diriez-vous http://www.javatuples.org/index.html je l'ai trouvé très utile.
Les javatuples vous proposent des classes de tuple de un à dix éléments:
la source
Pair
et je pouvais imaginer utiliserTriplet
peut-être une fois tous les 50 ans. Maintenant, j'utilise Lombok et crée une petite classe de 4 lignes chaque fois que j'ai besoin d'une paire. Donc "10 de trop" est exact.Bottom (0 element)
cours? :)Cela dépend de l'utilisation que vous souhaitez en faire. La raison typique de le faire est d'itérer sur les cartes, pour lesquelles vous faites simplement cela (Java 5+):
la source
android fournit la
Pair
classe ( http://developer.android.com/reference/android/util/Pair.html ), voici l'implémentation:la source
Objects.equal(..)
nécessite la bibliothèque Guava.Objects.equals(...)
en Java depuis 2011 (1.7).Le plus gros problème est probablement que l'on ne peut pas garantir l'immuabilité sur A et B (voir Comment s'assurer que les paramètres de type sont immuables ) donc
hashCode()
peut donner des résultats incohérents pour la même paire après avoir été insérée dans une collection par exemple (cela donnerait un comportement indéfini , voir Définir des égaux en termes de champs modifiables ). Pour une classe de paires particulière (non générique), le programmeur peut garantir l'immuabilité en choisissant soigneusement A et B comme immuables.Quoi qu'il en soit, effacer les avertissements génériques de la réponse de @ PeterLawrey (java 1.7):
Ajouts / corrections très appréciés :) En particulier, je ne suis pas sûr de mon utilisation
Pair<?, ?>
.Pour plus d'informations sur les raisons de cette syntaxe, voir Assurez - vous que les objets implémentent Comparable et pour une explication détaillée Comment implémenter une
max(Comparable a, Comparable b)
fonction générique en Java?la source
À mon avis, il n'y a pas de paire en Java car, si vous souhaitez ajouter des fonctionnalités supplémentaires directement sur la paire (par exemple, comparable), vous devez délimiter les types. En C ++, nous ne nous en soucions pas, et si les types composant une paire n'en ont pas
operator <
,pair::operator <
ils ne se compileront pas aussi bien.Un exemple de comparable sans limite:
Un exemple de Comparable avec la vérification à la compilation pour savoir si les arguments de type sont comparables:
C'est bien, mais cette fois, vous ne pouvez pas utiliser des types non comparables comme arguments de type dans Pair. On peut utiliser beaucoup de comparateurs pour Pair dans certaines classes utilitaires, mais les gens C ++ peuvent ne pas l'obtenir. Une autre façon est d'écrire beaucoup de classes dans une hiérarchie de types avec différentes limites sur les arguments de type, mais il y a trop de limites possibles et leurs combinaisons ...
la source
JavaFX (fourni avec Java 8) a la classe Pair <A, B>
la source
hashCode()
. Notez que Java lui-même n'appelle pas cette méthode. C'est pour le code utilisateur, y compris les bibliothèques.Comme beaucoup d'autres l'ont déjà dit, cela dépend vraiment du cas d'utilisation si une classe Pair est utile ou non.
Je pense que pour une fonction d'assistance privée, il est tout à fait légitime d'utiliser une classe Pair si cela rend votre code plus lisible et ne vaut pas la peine de créer une autre classe de valeur avec tout son code de plaque de chaudière.
D'un autre côté, si votre niveau d'abstraction vous oblige à documenter clairement la sémantique de la classe qui contient deux objets ou valeurs, alors vous devez écrire une classe pour elle. C'est généralement le cas si les données sont un objet métier.
Comme toujours, cela nécessite un jugement avisé.
Pour votre deuxième question, je recommande la classe Pair des bibliothèques Apache Commons. Celles-ci peuvent être considérées comme des bibliothèques standard étendues pour Java:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html
Vous pouvez également consulter EqualsBuilder , HashCodeBuilder et ToStringBuilder d' Apache Commons qui simplifient l'écriture des classes de valeur pour vos objets métier.
la source
Vous pouvez utiliser la classe utilitaire javafx,
Pair
qui sert le même objectif que la paire <> en c ++. https://docs.oracle.com/javafx/2/api/javafx/util/Pair.htmlla source
Les bonnes nouvelles
JavaFX
ont une paire de valeurs clés.ajoutez simplement javafx en tant que dépendance et importez
javafx.util.Pair
;et utilisez simplement comme dans
c++
.par exemple
la source
L' interface Map.Entry est assez proche de la paire c ++. Regardez l'implémentation concrète, comme AbstractMap.SimpleEntry et AbstractMap.SimpleImmutableEntry Le premier élément est getKey () et le second est getValue ().
la source
la source
Selon la nature du langage Java, je suppose que les gens n'ont pas réellement besoin d'un
Pair
, une interface est généralement ce dont ils ont besoin. Voici un exemple:Ainsi, lorsque les utilisateurs souhaitent renvoyer deux valeurs, ils peuvent effectuer les opérations suivantes:
C'est une solution assez légère, et elle répond à la question "Quelle est la sémantique d'un
Pair<L,R>
?". La réponse est, il s'agit d'une interface avec deux types (peut-être différents), et il a des méthodes pour retourner chacun d'eux. C'est à vous d'y ajouter plus de sémantique. Par exemple, si vous utilisez Position et voulez VRAIMENT l'indiquer dans votre code, vous pouvez définirPositionX
etPositionY
qui contientInteger
, pour constituer unPair<PositionX,PositionY>
. Si JSR 308 est disponible, vous pouvez également utiliserPair<@PositionX Integer, @PositionY Ingeger>
pour simplifier cela.EDIT: Une chose que je dois indiquer ici est que la définition ci-dessus relie explicitement le nom du paramètre de type et le nom de la méthode. C'est une réponse à ceux qui soutiennent qu'il y a un
Pair
manque d'informations sémantiques. En fait, la méthodegetL
signifie "donnez-moi l'élément qui correspond au type de paramètre de type L", ce qui signifie quelque chose.EDIT: Voici une classe utilitaire simple qui peut vous faciliter la vie:
usage:
la source
equals
,hashCode
ettoString
?toString
vous avez besoin de plus de connaissances sur la relation entre les deux champs.class
pourrait être mieux qu'un simpleinterface
car il peut mettre en œuvre ces choses.Bien qu'ils soient syntaxiquement similaires, Java et C ++ ont des paradigmes très différents. Écrire C ++ comme Java est mauvais C ++, et écrire Java comme C ++ est mauvais Java.
Avec un IDE basé sur la réflexion comme Eclipse, l'écriture des fonctionnalités nécessairement d'une classe "pair" est rapide et simple. Créez une classe, définissez deux champs, utilisez les différentes options du menu "Générer XX" pour remplir la classe en quelques secondes. Vous devrez peut-être taper un "compareTo" très rapidement si vous vouliez l'interface Comparable.
Avec des options de déclaration / définition distinctes dans le langage, les générateurs de code C ++ ne sont pas si bons, donc l'écriture manuelle de petites classes utilitaires prend plus de temps. Parce que la paire est un modèle, vous n'avez pas à payer pour les fonctions que vous n'utilisez pas, et la fonction typedef permet d'attribuer des noms de caractères significatifs au code, de sorte que les objections concernant "pas de sémantique" ne tiennent pas vraiment.
la source
La paire serait une bonne chose, pour être une unité de construction de base pour des génériques complexes, par exemple, cela vient de mon code:
C'est la même chose que le tuple de Haskell
la source
Pair
c'est optimal car il n'y a pas de sémantique particulière. Avoir un nom clair pour un concept clair est bien, mais chercher un nom où "premier" et "second" fonctionnent bien ne l'est pas.Objet de manière simple [] - peut être utilisé comme n'importe quel tuple de dimension
la source
Pour les langages de programmation comme Java, la structure de données alternative utilisée par la plupart des programmeurs pour représenter des structures de données de type paire est deux tableaux, et les données sont accessibles via le même index
exemple: http://www-igm.univ-mlv.fr/~lecroq/string/node8.html#SECTION0080
Ce n'est pas idéal car les données doivent être liées ensemble, mais elles s'avèrent également assez bon marché. De plus, si votre cas d'utilisation nécessite de stocker des coordonnées, il est préférable de créer votre propre structure de données.
J'ai quelque chose comme ça dans ma bibliothèque
la source
Vous pouvez utiliser la bibliothèque AutoValue de Google - https://github.com/google/auto/tree/master/value .
Vous créez une très petite classe abstraite et l'annotez avec @AutoValue et le processeur d'annotation génère pour vous une classe concrète qui a une valeur sémantique.
la source
Voici quelques bibliothèques qui ont plusieurs degrés de tuples pour votre commodité:
D'autres bibliothèques ont été mentionnées comme contenant au moins le
Pair
tuple.Plus précisément, dans le contexte d'une programmation fonctionnelle qui utilise beaucoup de typage structurel, plutôt que de typage nominal ( comme le préconise la réponse acceptée ), ces bibliothèques et leurs tuples sont très utiles.
la source
Brian Goetz, Paul Sandoz et Stuart Marks expliquent pourquoi lors de la session d'AQ à Devoxx'14.
Avoir une classe de paires génériques dans la bibliothèque standard se transformera en dette technique une fois les types de valeur introduits.
Voir aussi: Java SE 8 a-t-il des paires ou des tuples?
la source
une autre implémentation laconique de lombok
la source
J'ai remarqué que toutes les implémentations de paires éparpillées ici attribuent une signification à l'ordre des deux valeurs. Quand je pense à une paire, je pense à une combinaison de deux éléments dans lesquels l'ordre des deux n'a pas d'importance. Voici mon implémentation d'une paire non ordonnée, avec
hashCode
etequals
remplaçant pour garantir le comportement souhaité dans les collections. Également clonable.Cette implémentation a été correctement testée à l'unité et son utilisation dans un ensemble et une carte a été testée.
Remarquez que je ne prétends pas publier cela dans le domaine public. Ceci est du code que je viens d'écrire pour une utilisation dans une application, donc si vous allez l'utiliser, veuillez vous abstenir de faire une copie directe et déranger les commentaires et les noms un peu. Attraper ma dérive?
la source
Si quelqu'un veut une version simple et facile à utiliser, je l'ai mise à disposition sur https://github.com/lfac-pt/Java-Pair . De plus, les améliorations sont les bienvenues!
la source
com.sun.tools.javac.util.Pair est une implémentation simple d'une paire. Il se trouve dans jdk1.7.0_51 \ lib \ tools.jar.
À part org.apache.commons.lang3.tuple.Pair, ce n'est pas seulement une interface.
la source
utilisation:
Immuable, seulement une paire!
la source
Pair<Object, Object> pair = Pair.createPair("abc", "def")
mais je pense qu'il faut écrirePair.createPair((Object)"abc", (Object)"def")
avec votre code?@SuppressWarnings("unchecked") public static <K, V, X, Y> Pair<X, Y> createPair(K key, V value) { return new Pair<X, Y>((X) key, (Y) value); }
mais je ne sais pas si c'est une bonne pratiquenew Pair<Object, Object>("abc", "def")
était le plus fiable de mes expériences.