Quel est l'équivalent de la paire C++ en Java?

y a-t-il une bonne raison pour qu'il n'y ait pas de Pair<L,R> en Java? Quel serait l'équivalent de cette construction C++? Je préfère éviter de réimplanter mon propre.

il semble que 1.6 fournit quelque chose de similaire ( AbstractMap.SimpleEntry<K,V> ), mais cela semble assez alambiqué.

602
demandé sur Md. Abu Nafee Ibna Zahid 2008-10-01 08:48:41

30 réponses

Dans un thread sur comp.lang.java.help , Chasseur Gratzner donne des arguments contre la présence d'un Pair construire en Java. L'argument principal est qu'une classe Pair ne Véhicule pas de sémantique sur la relation entre les deux valeurs (comment savez-vous ce que "première" et "seconde" signifie ?).

une meilleure pratique est d'écrire une classe très simple, comme celle proposée par Mike, pour chaque application que vous auriez faite de la Pair de la classe. Map.Entry est un exemple de paire que son sens en son nom.

Pour résumer, à mon avis, il est préférable d'avoir une classe Position(x,y) , une classe Range(begin,end) et une classe Entry(key,value) plutôt qu'un générique Pair(first,second) qui ne me dit rien sur ce qu'il est censé faire.

363
répondu Luc Touraille 2014-09-02 18:57:44

ici Java. Vous devez créer votre propre classe de paires sur mesure avec des classes descriptives et des noms de champ, et ne pas se rappeler que vous allez réinventer la roue en écrivant hashCode()/equals() ou en implémentant Comparable encore et encore.

138
répondu Andreas Krey 2010-02-27 10:41:54

HashMap compatible Paire de classe:

public class Pair<A, B> {
    private A first;
    private B second;

    public Pair(A first, B second) {
        super();
        this.first = first;
        this.second = second;
    }

    public int hashCode() {
        int hashFirst = first != null ? first.hashCode() : 0;
        int hashSecond = second != null ? second.hashCode() : 0;

        return (hashFirst + hashSecond) * hashSecond + hashFirst;
    }

    public boolean equals(Object other) {
        if (other instanceof Pair) {
            Pair otherPair = (Pair) other;
            return 
            ((  this.first == otherPair.first ||
                ( this.first != null && otherPair.first != null &&
                  this.first.equals(otherPair.first))) &&
             (  this.second == otherPair.second ||
                ( this.second != null && otherPair.second != null &&
                  this.second.equals(otherPair.second))) );
        }

        return false;
    }

    public String toString()
    { 
           return "(" + first + ", " + second + ")"; 
    }

    public A getFirst() {
        return first;
    }

    public void setFirst(A first) {
        this.first = first;
    }

    public B getSecond() {
        return second;
    }

    public void setSecond(B second) {
        this.second = second;
    }
}
100
répondu arturh 2009-09-01 12:42:46

la paire la plus courte que j'ai pu trouver est la suivante, en utilisant Lombok :

@Data
@AllArgsConstructor(staticName = "of")
public class Pair<F, S> {
    private F first;
    private S second;
}

il a tous les avantages de la réponse de @arturh (sauf la comparabilité), il a hashCode , equals , toString et un "constructeur" statique.

47
répondu Michael Piefel 2017-05-23 12:02:47
36
répondu Matunos 2014-05-05 08:34:39

une autre façon d'implémenter la paire avec.

  • public immuable fields, i.e. simple data structure.
  • Comparable.
  • Simple hachage et d'égal à égal.
  • Simple usine de sorte que vous n'avez pas à fournir les types. par exemple, Paire.("bonjour", 1);

    public class Pair<FIRST, SECOND> implements Comparable<Pair<FIRST, SECOND>> {
    
        public final FIRST first;
        public final SECOND second;
    
        private Pair(FIRST first, SECOND second) {
            this.first = first;
            this.second = second;
        }
    
        public static <FIRST, SECOND> Pair<FIRST, SECOND> of(FIRST first,
                SECOND second) {
            return new Pair<FIRST, SECOND>(first, second);
        }
    
        @Override
        public int compareTo(Pair<FIRST, SECOND> o) {
            int cmp = compare(first, o.first);
            return cmp == 0 ? compare(second, o.second) : cmp;
        }
    
        // todo move this to a helper class.
        private static int compare(Object o1, Object o2) {
            return o1 == null ? o2 == null ? 0 : -1 : o2 == null ? +1
                    : ((Comparable) o1).compareTo(o2);
        }
    
        @Override
        public int hashCode() {
            return 31 * hashcode(first) + hashcode(second);
        }
    
        // todo move this to a helper class.
        private static int hashcode(Object o) {
            return o == null ? 0 : o.hashCode();
        }
    
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Pair))
                return false;
            if (this == obj)
                return true;
            return equal(first, ((Pair) obj).first)
                    && equal(second, ((Pair) obj).second);
        }
    
        // todo move this to a helper class.
        private boolean equal(Object o1, Object o2) {
            return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2));
        }
    
        @Override
        public String toString() {
            return "(" + first + ", " + second + ')';
        }
    }
    
31
répondu Peter Lawrey 2012-12-01 15:54:44

pourquoi pas http://www.javatuples.org/index.html Je l'ai trouvé très utile.

le javatuples vous offre des classes de tuples d'un à dix éléments:

Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)
Quartet<A,B,C,D> (4 elements)
Quintet<A,B,C,D,E> (5 elements)
Sextet<A,B,C,D,E,F> (6 elements)
Septet<A,B,C,D,E,F,G> (7 elements)
Octet<A,B,C,D,E,F,G,H> (8 elements)
Ennead<A,B,C,D,E,F,G,H,I> (9 elements)
Decade<A,B,C,D,E,F,G,H,I,J> (10 elements)
27
répondu cyberoblivion 2012-03-01 19:02:17

Cela dépend de ce que vous voulez l'utiliser pour. La raison typique de le faire est d'itérer sur des cartes, pour lesquelles vous faites simplement ceci (Java 5+):

Map<String, Object> map = ... ; // just an example
for (Map.Entry<String, Object> entry : map.entrySet()) {
  System.out.printf("%s -> %s\n", entry.getKey(), entry.getValue());
}
12
répondu cletus 2008-10-01 04:53:59

android fournit Pair classe ( http://developer.android.com/reference/android/util/Pair.html ), voici la mise en œuvre:

public class Pair<F, S> {
    public final F first;
    public final S second;

    public Pair(F first, S second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Pair)) {
            return false;
        }
        Pair<?, ?> p = (Pair<?, ?>) o;
        return Objects.equal(p.first, first) && Objects.equal(p.second, second);
    }

    @Override
    public int hashCode() {
        return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
    }

    public static <A, B> Pair <A, B> create(A a, B b) {
        return new Pair<A, B>(a, b);
    }
}
12
répondu sherpya 2014-05-05 08:45:32

le plus gros problème est probablement qu'on ne peut pas assurer l'immutabilité sur A et B (Voir comment s'assurer que les paramètres de type sont immuables ) de sorte que hashCode() peut donner des résultats incohérents pour la même paire après est inséré dans une collection par exemple (cela donnerait un comportement non défini, voir définir des égaux en termes de champs mutables ). Pour une classe de paire particulière (non générique), le programmeur peut assurer: immutabilité En choisissant soigneusement A et B Pour Être immuable.

en tout cas, effacant les avertissements de generic de la réponse de @PeterLawrey (java 1.7):

public class Pair<A extends Comparable<? super A>,
                    B extends Comparable<? super B>>
        implements Comparable<Pair<A, B>> {

    public final A first;
    public final B second;

    private Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }

    public static <A extends Comparable<? super A>,
                    B extends Comparable<? super B>>
            Pair<A, B> of(A first, B second) {
        return new Pair<A, B>(first, second);
    }

    @Override
    public int compareTo(Pair<A, B> o) {
        int cmp = o == null ? 1 : (this.first).compareTo(o.first);
        return cmp == 0 ? (this.second).compareTo(o.second) : cmp;
    }

    @Override
    public int hashCode() {
        return 31 * hashcode(first) + hashcode(second);
    }

    // TODO : move this to a helper class.
    private static int hashcode(Object o) {
        return o == null ? 0 : o.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Pair))
            return false;
        if (this == obj)
            return true;
        return equal(first, ((Pair<?, ?>) obj).first)
                && equal(second, ((Pair<?, ?>) obj).second);
    }

    // TODO : move this to a helper class.
    private boolean equal(Object o1, Object o2) {
        return o1 == o2 || (o1 != null && o1.equals(o2));
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ')';
    }
}

Ajouts/corrections beaucoup bienvenue :) En particulier, je ne suis pas tout à fait sûr de mon utilisation de Pair<?, ?> .

pour plus d'informations sur la raison pour laquelle cette syntaxe voir S'assurer que les objets mettent en œuvre Comparable et pour une explication détaillée comment implémenter une fonction générique max(Comparable a, Comparable b) en Java?

8
répondu Mr_and_Mrs_D 2017-11-15 17:09:48

à mon avis, Il n'y a pas de paire en Java parce que, si vous voulez ajouter des fonctionnalités supplémentaires directement sur la paire (par exemple Comparable), vous devez lier les types. En C++, on s'en fout , et si les types composant une paire n'ont pas operator < , le pair::operator < ne se compilera pas aussi bien.

un exemple de Comparable sans limite:

public class Pair<F, S> implements Comparable<Pair<? extends F, ? extends S>> {
    public final F first;
    public final S second;
    /* ... */
    public int compareTo(Pair<? extends F, ? extends S> that) {
        int cf = compare(first, that.first);
        return cf == 0 ? compare(second, that.second) : cf;
    }
    //Why null is decided to be less than everything?
    private static int compare(Object l, Object r) {
        if (l == null) {
            return r == null ? 0 : -1;
        } else {
            return r == null ? 1 : ((Comparable) (l)).compareTo(r);
        }
    }
}

/* ... */

Pair<Thread, HashMap<String, Integer>> a = /* ... */;
Pair<Thread, HashMap<String, Integer>> b = /* ... */;
//Runtime error here instead of compile error!
System.out.println(a.compareTo(b));

un exemple de vérification Comparable à la compilation pour savoir si les arguments de type sont comparable:

public class Pair<
        F extends Comparable<? super F>, 
        S extends Comparable<? super S>
> implements Comparable<Pair<? extends F, ? extends S>> {
    public final F first;
    public final S second;
    /* ... */
    public int compareTo(Pair<? extends F, ? extends S> that) {
        int cf = compare(first, that.first);
        return cf == 0 ? compare(second, that.second) : cf;
    }
    //Why null is decided to be less than everything?
    private static <
            T extends Comparable<? super T>
    > int compare(T l, T r) {
        if (l == null) {
            return r == null ? 0 : -1;
        } else {
            return r == null ? 1 : l.compareTo(r);
        }
    }
}

/* ... */

//Will not compile because Thread is not Comparable<? super Thread>
Pair<Thread, HashMap<String, Integer>> a = /* ... */;
Pair<Thread, HashMap<String, Integer>> b = /* ... */;
System.out.println(a.compareTo(b));

c'est bien, mais cette fois vous ne pouvez pas utiliser des types non comparables comme arguments de type en paire. On peut utiliser beaucoup de comparateurs pour la paire dans une certaine classe utilitaire, mais les gens de C++ peuvent ne pas l'avoir. Une autre façon est d'écrire beaucoup de classes dans une hiérarchie de type avec des limites différentes sur les arguments de type, mais il y a trop de limites possibles et leurs combinaisons...

5
répondu MaxBuzz 2010-12-15 18:40:08

JavaFX (qui est livré avec Java 8) a la paire < A, B > Classe

5
répondu CarrKnight 2015-04-20 23:04:09

comme beaucoup d'autres l'ont déjà dit, Cela dépend vraiment du cas d'utilisation si une classe de paires est utile ou non.

je pense que pour une fonction d'aide privée il est tout à fait légitime d'utiliser une classe de paire si cela rend votre code plus lisible et ne vaut pas la peine de créer encore une autre classe de valeur avec tout son code de la chaudière.

, d'autre part, si votre niveau d'abstraction nécessite de documenter clairement la sémantique de la classe qui contient deux objets ou valeurs, alors vous devriez écrire une classe pour elle. Généralement c'est le cas si les données est un objet métier.

comme toujours, il exige un jugement habile.

pour votre deuxième question, je vous recommande la classe paire 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 pourriez aussi vouloir jeter un oeil à Apache Commons' EqualsBuilder , HashCodeBuilder et ToStringBuilder qui simplifient les classes de valeur d'écriture pour vos objets d'affaires.

5
répondu Peter Goetz 2015-11-10 20:36:26

de la Carte.Entrée interface viennent 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 ().

4
répondu Nikunj Bhagat 2015-05-15 17:36:23

Bonne nouvelle Java , a ajouté la valeur de la clé de Paire .

il suffit d'importer javafx.util.Pair ;

et utiliser simplement comme dans c++ .

Pair < Key , Value > 

p.ex.

Pair < Integer , Integer > pr = new Pair<Integer , Integer>()

pr.get(key); // will return corresponding value
4
répondu RAJAN_PARMAR 2016-01-24 14:43:55
Collections.singletonMap(left, rigth);
4
répondu Denis Arkharov 2016-02-12 09:16:57

vous pouvez utiliser la classe d'utilité javafx, Pair qui sert le même but que la paire <> en c++. https://docs.oracle.com/javafx/2/api/javafx/util/Pair.html

4
répondu Sathyanarayanan Ganesan 2016-04-08 07:13:31

selon la nature du langage Java, je suppose que les gens n'ont pas réellement besoin d'une Pair , une interface est généralement ce dont ils ont besoin. Voici un exemple:

interface Pair<L, R> {
    public L getL();
    public R getR();
}

ainsi, quand les gens veulent retourner deux valeurs, ils peuvent faire ce qui suit:

... //Calcuate the return value
final Integer v1 = result1;
final String v2 = result2;
return new Pair<Integer, String>(){
    Integer getL(){ return v1; }
    String getR(){ return v2; }
}

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 construire avec deux (mai être différents) types, et il a des méthodes pour retourner chacun d'eux. C'est à vous d'ajouter d'autres sémantique. Par exemple, si vous utilisez la Position et voulez vraiment l'indiquer dans votre code , vous pouvez définir PositionX et PositionY qui contient Integer , pour constituer un Pair<PositionX,PositionY> . Si JSR 308 est disponible, vous pouvez également utiliser Pair<@PositionX Integer, @PositionY Ingeger> pour simplifier.

EDIT: Une chose que je devrais indiquer ici est que la définition ci-dessus se rapporte explicitement le type nom du paramètre et nom de la méthode. C'est une réponse à ceux qui soutiennent qu'un Pair est un manque d'information sémantique. En fait, la méthode getL signifie "Donnez-moi l'élément qui correspond au type de paramètre de type L", Ce Qui veut dire quelque chose.

EDIT: Voici une classe utilitaire simple qui peut rendre la vie plus facile:

class Pairs {
    static <L,R> Pair<L,R> makePair(final L l, final R r){
        return new Pair<L,R>(){
            public L getL() { return l; }
            public R getR() { return r; }   
        };
    }
}

utilisation:

return Pairs.makePair(new Integer(100), "123");
3
répondu Earth Engine 2012-11-08 23:58:06

bien que 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, écrire la fonctionnalité nécessaire d'une classe" paire " est rapide et simple. Créer une classe, définir deux champs, utiliser les différentes options du menu "Generate XX" pour remplir la classe en quelques secondes. Peut-être que tu devrais taper un "compareTo" très vite si tu je voulais une interface Comparable.

avec des options de déclaration / définition séparées dans le langage C++ Les générateurs de code ne sont pas si bons, donc écrire à la main peu de classes d'utilité est plus fastidieux. Parce que la paire est un modèle, vous n'avez pas à payer pour les fonctions que vous n'utilisez pas, et la facilité typedef permet d'assigner des noms de caractères significatifs au code, de sorte que les objections à propos de "aucune sémantique" ne tiennent pas vraiment debout.

3
répondu gerardw 2014-02-17 21:19:06

paire serait une bonne chose, pour être une unité de construction de base pour un génériques complexes, par exemple, ce est de mon code:

WeakHashMap<Pair<String, String>, String> map = ...

C'est la même chose que Haskell Tuple

2
répondu Illarion Kovalchuk 2010-02-03 14:44:10

pour les langages de programmation comme Java, la structure de données alternative utilisée par la plupart des programmeurs pour représenter les structures de données en paires sont 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 devraient être reliées entre elles, mais il s'avère aussi qu'elles sont assez bon marché. En outre, si votre utilisation nécessite le stockage des coordonnées il est alors préférable de construire votre propre structure de données.

j'ai quelque chose comme ça dans ma bibliothèque

public class Pair<First,Second>{.. }
2
répondu Swapneel Patil 2013-03-18 02:48:04

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 une classe concrète pour vous qui a une valeur sémantique.

2
répondu Shahar 2014-10-06 16:42:04

Voici quelques bibliothèques qui ont plusieurs degrés de tuples pour votre commodité:

  • JavaTuples . Tuples de degré 1-10 est tout ce qu'il a.
  • JavaSlang . Tuples de degré 0-8 et beaucoup d'autres goodies fonctionnels.
  • jOOλ . Tuples de degré 0-16 et d'autres goodies fonctionnelles. (Désistement, je travaille pour le responsable société)
  • Fonctionnel Java . Tuples de degré 0-8 et beaucoup d'autres goodies fonctionnels.

D'autres bibliothèques ont été mentionnées pour contenir au moins le Pair tuple.

plus précisément, dans le contexte de la programmation fonctionnelle qui utilise beaucoup de typage structurel, plutôt que de typage nominal ( tel que recommandé dans la réponse acceptée ), ceux les bibliothèques et leurs n-uplets sont très pratiques.

2
répondu Lukas Eder 2017-05-23 12:02:47

Brian Goetz, Paul Sandoz et Stuart Marques "151910920 d'expliquer" pourquoi au cours de QA session à Devoxx'14.

ayant la classe de paire générique dans la bibliothèque standard se transformera en dette technique une fois types de valeur introduit.

Voir aussi: est-ce que Java SE 8 a des paires ou des Tuples?

2
répondu user2418306 2017-05-23 12:18:26

façon Simple Object [] - peut être utiliser que n'importe quel dimention tuple

1
répondu Testus 2010-09-29 06:44:19

j'ai remarqué que toutes les implémentations de paire étaient éparpillées ici attribuent un sens à l'ordre des deux valeurs. Quand je pense que d'une paire, je pense à une combinaison de deux éléments dont l'un des deux n'est d'aucune importance. Voici ma mise en œuvre d'une paire non ordonnée, avec les dérogations hashCode et equals pour assurer le comportement désiré dans les collections. Aussi clonable.

/**
 * The class <code>Pair</code> models a container for two objects wherein the
 * object order is of no consequence for equality and hashing. An example of
 * using Pair would be as the return type for a method that needs to return two
 * related objects. Another good use is as entries in a Set or keys in a Map
 * when only the unordered combination of two objects is of interest.<p>
 * The term "object" as being a one of a Pair can be loosely interpreted. A
 * Pair may have one or two <code>null</code> entries as values. Both values
 * may also be the same object.<p>
 * Mind that the order of the type parameters T and U is of no importance. A
 * Pair&lt;T, U> can still return <code>true</code> for method <code>equals</code>
 * called with a Pair&lt;U, T> argument.<p>
 * Instances of this class are immutable, but the provided values might not be.
 * This means the consistency of equality checks and the hash code is only as
 * strong as that of the value types.<p>
 */
public class Pair<T, U> implements Cloneable {

    /**
     * One of the two values, for the declared type T.
     */
    private final T object1;
    /**
     * One of the two values, for the declared type U.
     */
    private final U object2;
    private final boolean object1Null;
    private final boolean object2Null;
    private final boolean dualNull;

    /**
     * Constructs a new <code>Pair&lt;T, U&gt;</code> with T object1 and U object2 as
     * its values. The order of the arguments is of no consequence. One or both of
     * the values may be <code>null</code> and both values may be the same object.
     *
     * @param object1 T to serve as one value.
     * @param object2 U to serve as the other value.
     */
    public Pair(T object1, U object2) {

        this.object1 = object1;
        this.object2 = object2;
        object1Null = object1 == null;
        object2Null = object2 == null;
        dualNull = object1Null && object2Null;

    }

    /**
     * Gets the value of this Pair provided as the first argument in the constructor.
     *
     * @return a value of this Pair.
     */
    public T getObject1() {

        return object1;

    }

    /**
     * Gets the value of this Pair provided as the second argument in the constructor.
     *
     * @return a value of this Pair.
     */
    public U getObject2() {

        return object2;

    }

    /**
     * Returns a shallow copy of this Pair. The returned Pair is a new instance
     * created with the same values as this Pair. The values themselves are not
     * cloned.
     *
     * @return a clone of this Pair.
     */
    @Override
    public Pair<T, U> clone() {

        return new Pair<T, U>(object1, object2);

    }

    /**
     * Indicates whether some other object is "equal" to this one.
     * This Pair is considered equal to the object if and only if
     * <ul>
     * <li>the Object argument is not null,
     * <li>the Object argument has a runtime type Pair or a subclass,
     * </ul>
     * AND
     * <ul>
     * <li>the Object argument refers to this pair
     * <li>OR this pair's values are both null and the other pair's values are both null
     * <li>OR this pair has one null value and the other pair has one null value and
     * the remaining non-null values of both pairs are equal
     * <li>OR both pairs have no null values and have value tuples &lt;v1, v2> of
     * this pair and &lt;o1, o2> of the other pair so that at least one of the
     * following statements is true:
     * <ul>
     * <li>v1 equals o1 and v2 equals o2
     * <li>v1 equals o2 and v2 equals o1
     * </ul>
     * </ul>
     * In any other case (such as when this pair has two null parts but the other
     * only one) this method returns false.<p>
     * The type parameters that were used for the other pair are of no importance.
     * A Pair&lt;T, U> can return <code>true</code> for equality testing with
     * a Pair&lt;T, V> even if V is neither a super- nor subtype of U, should
     * the the value equality checks be positive or the U and V type values
     * are both <code>null</code>. Type erasure for parameter types at compile
     * time means that type checks are delegated to calls of the <code>equals</code>
     * methods on the values themselves.
     *
     * @param obj the reference object with which to compare.
     * @return true if the object is a Pair equal to this one.
     */
    @Override
    public boolean equals(Object obj) {

        if(obj == null)
            return false;

        if(this == obj)
            return true;

        if(!(obj instanceof Pair<?, ?>))
            return false;

        final Pair<?, ?> otherPair = (Pair<?, ?>)obj;

        if(dualNull)
            return otherPair.dualNull;

        //After this we're sure at least one part in this is not null

        if(otherPair.dualNull)
            return false;

        //After this we're sure at least one part in obj is not null

        if(object1Null) {
            if(otherPair.object1Null) //Yes: this and other both have non-null part2
                return object2.equals(otherPair.object2);
            else if(otherPair.object2Null) //Yes: this has non-null part2, other has non-null part1
                return object2.equals(otherPair.object1);
            else //Remaining case: other has no non-null parts
                return false;
        } else if(object2Null) {
            if(otherPair.object2Null) //Yes: this and other both have non-null part1
                return object1.equals(otherPair.object1);
            else if(otherPair.object1Null) //Yes: this has non-null part1, other has non-null part2
                return object1.equals(otherPair.object2);
            else //Remaining case: other has no non-null parts
                return false;
        } else {
            //Transitive and symmetric requirements of equals will make sure
            //checking the following cases are sufficient
            if(object1.equals(otherPair.object1))
                return object2.equals(otherPair.object2);
            else if(object1.equals(otherPair.object2))
                return object2.equals(otherPair.object1);
            else
                return false;
        }

    }

    /**
     * Returns a hash code value for the pair. This is calculated as the sum
     * of the hash codes for the two values, wherein a value that is <code>null</code>
     * contributes 0 to the sum. This implementation adheres to the contract for
     * <code>hashCode()</code> as specified for <code>Object()</code>. The returned
     * value hash code consistently remain the same for multiple invocations
     * during an execution of a Java application, unless at least one of the pair
     * values has its hash code changed. That would imply information used for 
     * equals in the changed value(s) has also changed, which would carry that
     * change onto this class' <code>equals</code> implementation.
     *
     * @return a hash code for this Pair.
     */
    @Override
    public int hashCode() {

        int hashCode = object1Null ? 0 : object1.hashCode();
        hashCode += (object2Null ? 0 : object2.hashCode());
        return hashCode;

    }

}

cette mise en œuvre a été correctement testé à l'unité et le l'utilisation dans un Set et une carte a été testée.

notez que je ne prétends pas publier ceci dans le domaine public. C'est le code que je viens d'écrire pour les utiliser dans une application, donc si vous allez l'utiliser, s'il vous plaît s'abstenir de faire une copie directe et déconner avec les commentaires et les noms un peu. Attrapez ma dérive?

1
répondu G_H 2011-04-20 17:53:55

si quelqu'un veut une version morte-simple et facile à utiliser, j'ai mis à disposition ma version https://github.com/lfac-pt/Java-Pair . Les améliorations sont également les bienvenues!

1
répondu Luís Cardoso 2012-01-05 22:22:57

com.soleil.outils.javac.util.Pair est une simple implémentation d'une paire. Il peut être trouvé dans jdk1.7.0_51\lib\tools.pot.

autre que l'org.Apache.commun.lang3.n-uplet.Pair, ce n'est pas juste une interface.

1
répondu masterxilo 2014-05-05 08:46:49
public class Pair<K, V> {

    private final K element0;
    private final V element1;

    public static <K, V> Pair<K, V> createPair(K key, V value) {
        return new Pair<K, V>(key, value);
    }

    public Pair(K element0, V element1) {
        this.element0 = element0;
        this.element1 = element1;
    }

    public K getElement0() {
        return element0;
    }

    public V getElement1() {
        return element1;
    }

}

utilisation :

Pair<Integer, String> pair = Pair.createPair(1, "test");
pair.getElement0();
pair.getElement1();

immuable, seulement une paire !

0
répondu Baptiste 2011-12-09 10:55:59

beaucoup de gens affichent Pair code qui est utilisable comme une clé dans une carte...Si vous essayez d'utiliser une paire comme une clé de hachage (un idiome commun), assurez-vous de vérifier Guava Table<R,C,V> : http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table . Ils donnent l'exemple suivant d'utilisation, pour les bords de graphe:

Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create();
weightedGraph.put(v1, v2, 4);
weightedGraph.put(v1, v3, 20);
weightedGraph.put(v2, v3, 5);

weightedGraph.row(v1); // returns a Map mapping v2 to 4, v3 to 20
weightedGraph.column(v3); // returns a Map mapping v1 to 20, v2 to 5

a Table mappe deux clés à une seule valeur, et fournit des recherches efficaces pour les deux types de clés, seul. J'ai commencé à utiliser cette structure de données au lieu d'un Map<Pair<K1,K2>, V> dans de nombreuses parties de mon code. Il y a des tableaux, des arborescences et d'autres implémentations pour les utilisations denses et éparses, avec l'option de spécifier vos propres classes de cartes intermédiaires.

0
répondu Andrew Mao 2012-12-29 20:31:39