716 Stimmen

Was ist das Äquivalent von C++ Pair<L,R> in Java?

Gibt es einen guten Grund, warum es in Java kein Pair gibt? Was wäre das Äquivalent zu diesem C++-Konstrukt? Ich würde es lieber vermeiden, mein eigenes neu zu implementieren.

Es scheint, dass 1.6 etwas Ähnliches bereitstellt (AbstractMap.SimpleEntry), aber das sieht ziemlich verworren aus.

10 Stimmen

Warum ist AbstractMap.SimpleEntry umständlich?

0 Stimmen

Sehen Sie meine Antwort stackoverflow.com/a/16089164/173149, wo ich AbstractMap.SimpleImmutableEntry ohne Probleme verwende (kompliziertes Beispiel).

0 Stimmen

SimpleEntry hat drei Methoden, die nicht von Object vererbt wurden. Warum sollte es "verschachtelt" sein?

425voto

Luc Touraille Punkte 76149

In einem Thread über comp.lang.java.help gibt Hunter Gratzner einige Argumente gegen das Vorhandensein eines Pair-Konstrukts in Java. Das Hauptargument ist, dass eine Klasse Pair keine Semantik über die Beziehung zwischen den beiden Werten vermittelt (wie weiß man, was "erstes" und "zweites" bedeuten?).

Es ist eine bessere Praxis, für jede Anwendung, die man mit der Pair-Klasse gemacht hätte, eine sehr einfache Klasse zu schreiben, wie die von Mike vorgeschlagene. Map.Entry ist ein Beispiel für ein Paar, das seine Bedeutung in seinem Namen trägt.

Zusammenfassend ist es meiner Meinung nach besser, eine Klasse Position(x,y), eine Klasse Range(begin,end) und eine Klasse Entry(key,value) zu haben, anstelle eines generischen Pair(first,second), das mir nichts darüber sagt, was es tun soll.

185 Stimmen

Gratzner ist pingelig. Wir sind sehr daran interessiert, einen einzelnen Wert als primitiv oder eingebaute Klasse zurückzugeben, ohne ihn in einer Klasse zu kapseln. Wenn wir ein Tupel aus einem Dutzend Elementen zurückgeben würden, würde niemand widersprechen, dass es seine eigene Klasse haben sollte. Irgendwo in der Mitte gibt es eine (verschwommene) Grenze. Ich denke, unsere Echsenhirne können problemlos mit Paaren umgehen.

39 Stimmen

Ich stimme Ian zu. Java ermöglicht es Ihnen, int zurückzugeben; es zwingt Sie nicht dazu, jedes Mal, wenn Sie eine verwenden, ein Alias für int zu erstellen. Paare sind nicht sehr unterschiedlich.

5 Stimmen

Wenn wir ein Paar direkt in lokale Variablen entpacken oder es an eine Methode weiterleiten könnten, die zwei Argumente entgegennimmt, wäre Pair eine nützliche Klasse. Da wir es nicht so entpacken können, sieht es nicht so schlecht aus, eine sinnvolle Klasse zu erstellen und die Werte zusammenzuhalten. Und wenn Sie wirklich ein Paar trotz der Einschränkungen wollen, gibt es immer noch Object[2] + Casts :-)

168voto

Andreas Krey Punkte 5896

Dies ist Java. Sie müssen Ihre eigene maßgeschneiderte Pair-Klasse mit beschreibenden Klassen- und Feldnamen erstellen und sich nicht darum kümmern, dass Sie das Rad immer wieder neu erfinden, indem Sie hashCode()/equals() schreiben oder Comparable implementieren.

25 Stimmen

Die Java-Täuschung wäre in Ordnung gewesen, wenn Sie auf das Apache Commong Lang verwiesen hätten, das eine Pair-Klasse enthält.

6 Stimmen

Oder Sie könnten einfach SimpleImmutableEntry verwenden

0 Stimmen

Die häufigsten IDEs generieren automatisch einen geeigneten HashCode()/equals für Sie.

109voto

arturh Punkte 5966

HashMap kompatible Pair-Klasse:

public class Pair {
    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;
    }
}

146 Stimmen

Es ist wahrscheinlich eine gute Idee, die Setters zu löschen und first und second final zu machen, um das Paar unveränderlich zu machen. (Wenn jemand die Komponenten nach dem Verwenden als Hash-Schlüssel ändert, passieren seltsame Dinge).

23 Stimmen

Return "(" + first.toString() + ", " + second.toString() + ")" in der toString()-Methode kann zu NullPointerExceptions führen. Besser ist es: return "(" + first + ", " + second + ")";

6 Stimmen

Auch, gib entweder "final" an oder ändere die erste Zeile zu 'if (other != null && this.getClass() == other.getClass())'

58voto

Michael Piefel Punkte 16276

Das kürzeste Paar, das ich verwenden konnte, lautet wie folgt, und es verwendet Lombok:

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

Es hat alle Vorteile der Antwort von arturh (außer der Vergleichbarkeit), es hat hashCode, equals, toString und einen statischen "Konstruktor".

1 Stimmen

Nifty! Gemocht!

0 Stimmen

Mich nach Lombok einzuführen, unbezahlbar.

41voto

Matunos Punkte 519

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X