en Java?'/> en Java?'/> en Java?'/> Quel est l'équivalent de la paire C ++ <L, R> en Java? | abulletproofidea.com

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


Y at-il une bonne raison pour laquelle il n'y a pas Pair<L,R> en Java? Quel serait l'équivalent de cette construction C ++? Je préfère éviter de réimplémenter le mien.

Il paraît que 1.6 fournit quelque chose de similaire (AbstractMap.SimpleEntry<K,V>), mais cela semble assez compliqué.


595
2017-10-01 04:48


origine


Réponses:


Dans un fil sur comp.lang.java.help, Hunter Gratzner donne quelques arguments contre la présence d'un Pair construire en Java. L'argument principal est qu'une classe Pair ne transmet aucune sémantique sur la relation entre les deux valeurs (comment savez-vous ce que «premier» et «second» signifient?).

Une meilleure pratique consiste à écrire un cours très simple, comme celui que Mike a proposé, pour chaque application que vous auriez faite du Pair classe. Map.Entry est un exemple d'une paire qui porte sa signification dans son nom.

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


359
2017-10-01 08:18



C'est Java. Vous devez créer votre propre classe de paires avec des noms de classes et de champs descriptifs, et ne pas oublier que vous allez réinventer la roue en écrivant hashCode () / equals () ou en implémentant de façon répétitive.


137
2018-02-27 10:41



HashMap compatible classe de paire:

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;
    }
}

99
2018-03-24 12:55



La paire la plus courte que je pourrais 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.


46
2017-12-17 14:39



Apache Commons Lang 3.0+ a quelques classes de paires: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html


36
2018-03-13 00:21



Une autre façon d'implémenter Pair avec.

  • Champs publics immuables, c'est-à-dire structure de données simple.
  • Comparable.
  • Hash simple et égal.
  • Usine simple donc vous n'avez pas à fournir les types. par exemple. Pair.of ("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
2017-09-05 14:27



Que diriez-vous http://www.javatuples.org/index.html Je l'ai trouvé très utile.

Le javatuples vous offre des classes de tuple de 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)

26
2018-03-01 19:02



Cela dépend de ce que vous voulez l'utiliser. La raison typique est de parcourir les cartes, pour lesquelles vous faites simplement cela (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
2017-10-01 04:53



android fournit Pairclasse (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
2018-05-05 08:45



Le plus gros problème est probablement que l'on ne peut pas assurer l'immuabilité sur A et B (voir Comment s'assurer que les paramètres de type sont immuables) alors 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 indéfini, voir Définir égal en termes de champs modifiables). Pour une classe de paire particulière (non générique), le programmeur peut assurer l'immuabilité en choisissant soigneusement A et B pour être immuable.

Quoi qu'il en soit, effacer les avertissements du générique de la réponse @ 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 bienvenu :) En particulier je ne suis pas tout à fait sûr de mon utilisation de Pair<?, ?>.

Pour plus d'informations sur pourquoi cette syntaxe voir Assurez-vous que les objets implémentent des valeurs comparables et pour une explication détaillée Comment mettre en œuvre un générique max(Comparable a, Comparable b) fonctionner en Java?


8
2017-12-01 15:37