Using Pairs or 2-tuples in Java

670,879

Solution 1

I don't think there is a general purpose tuple class in Java but a custom one might be as easy as the following:

public class Tuple<X, Y> { 
  public final X x; 
  public final Y y; 
  public Tuple(X x, Y y) { 
    this.x = x; 
    this.y = y; 
  } 
} 

Of course, there are some important implications of how to design this class further regarding equality, immutability, etc., especially if you plan to use instances as keys for hashing.

Solution 2

javatuples is a dedicated project for tuples in Java.

Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)

Solution 3

Apache Commons provided some common java utilities including a Pair. It implements Map.Entry, Comparable and Serializable.

Solution 4

If you are looking for a built-in Java two-element tuple, try AbstractMap.SimpleEntry.

Solution 5

As an extension to @maerics nice answer, I've added a few useful methods:

public class Tuple<X, Y> { 
    public final X x; 
    public final Y y; 
    public Tuple(X x, Y y) { 
        this.x = x; 
        this.y = y; 
    }

    @Override
    public String toString() {
        return "(" + x + "," + y + ")";
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }

        if (!(other instanceof Tuple)){
            return false;
        }

        Tuple<X,Y> other_ = (Tuple<X,Y>) other;

        // this may cause NPE if nulls are valid values for x or y. The logic may be improved to handle nulls properly, if needed.
        return other_.x.equals(this.x) && other_.y.equals(this.y);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((x == null) ? 0 : x.hashCode());
        result = prime * result + ((y == null) ? 0 : y.hashCode());
        return result;
    }
}
Share:
670,879
syker
Author by

syker

Updated on October 30, 2021

Comments

  • syker
    syker over 2 years

    My Hashtable in Java would benefit from a value having a tuple structure. What data structure can I use in Java to do that?

    Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
    
  • Admin
    Admin over 13 years
    I think it would be better to declare x and y as public final and get rid of those getters.
  • Anoyz
    Anoyz almost 12 years
    That is not a tuple. It only hold pairs (tuples of length 2).
  • Kjellski
    Kjellski over 11 years
    I've used tuples a lot in C# and the documentation is really good if you would want to write a bigger one for your own: msdn.microsoft.com/de-de/library/vstudio/dd387036.aspx
  • Oliver
    Oliver almost 11 years
    The implementation provided by Apache Commons fulfills exactly what I needed. I am happy to have a working implementation.
  • athabaska
    athabaska over 10 years
    If x or y is String, equals method will be not be working ok.
  • djechlin
    djechlin over 10 years
    Less readable. If I saw this in code I'd wonder where the map is.
  • n611x007
    n611x007 over 10 years
    -1 (sorry). as @Anoyz told, this is not a tuple - it is a 2-tuple or a pair. Tuples can be created with arbitrary number of elements. -- Your definition may be depending on where do you came from, I guess.
  • n611x007
    n611x007 over 10 years
    Does it only cover tuples to 10-tuples?
  • n611x007
    n611x007 over 10 years
    could you paste the relevant part here, before groups close down or anything? SO encourages copying relevant information to on-site.
  • n611x007
    n611x007 over 10 years
    Well, the question seems to be wrong about tuples. Pairs != Tuples. Tuples are n-length, ie. any length.
  • n611x007
    n611x007 over 10 years
    Ah, the question is just wrong. Are these ordered? Can have duplicate elements? What about a tuple? ;)
  • n611x007
    n611x007 over 10 years
    This too suffers from the question's wrong assumption that tuples should be Pairs.... tuples are of any length, not just 2.
  • Alexei Averchenko
    Alexei Averchenko over 10 years
    @naxa Better something than nothing. Also, you can nest pairs.
  • rhgb
    rhgb over 10 years
    @naxa please re-check the question description and you may found a Pair is exactly what he need.
  • n611x007
    n611x007 over 10 years
    you are right in that and I may did wrong with pasting my view as comment in some answers, including yours. Unfortunatelly I tend to search questions based on their title; it's unclearness on the question's part that it uses a way more general title than the asker's actual problem.
  • Yago Méndez Vidal
    Yago Méndez Vidal over 10 years
    This is the actual solution as the one accepted will fail in the Hashtable (as requested in the question) since the hasCode() and equals() of 2 same couples will differ.
  • Yago Méndez Vidal
    Yago Méndez Vidal over 10 years
    As athabaska noted, just substitute the last line of equals() to return Objects.equals(other_.x == this.x) && Objects.equals(other_.y == this.y) in Java 7 or an equalily comparson with null check.
  • Yago Méndez Vidal
    Yago Méndez Vidal over 10 years
    This doesn't work. When used in Hashtable or HashMap (as requested) it fails since 2 different tuples with the same elements will provide different hash codes. equals() and hashCode() must be overriden.
  • maerics
    maerics over 10 years
    @YagoMéndezVidal: yes, the last sentence of my answer says "there are some important implications of how to design this class further regarding equality, immutability, etc., especially if you plan to use instances as keys for hashing."
  • Aram Kocharyan
    Aram Kocharyan over 10 years
    @YagoMéndezVidal good point, this was generated in Eclipse...
  • RustyTheBoyRobot
    RustyTheBoyRobot about 10 years
    @aem999 - The question you link to has been deleted.
  • thisdotnull
    thisdotnull about 10 years
  • supercat
    supercat about 10 years
    @naxa: In a language where generic types are distinguishable by the number of parameters, it's fine to types called Tuple<T1,T2>, Tuple<T1,T2,T3>, etc. The names are not good in Java, which does not allow such distinction, but that doesn't mean Tuple is not a good name for classes with hardcoded number of types in languages with "real" generic types.
  • supercat
    supercat about 10 years
    If a method is supposed to examine a double[] and compute the minimum, maximum, average, and standard deviation, having it store the values into a passed-in double[4] may be less elegant than having it use a type with named fields, but someone who wants to know what's going on will only have to read the documentation for the method, instead of having to also read the documentation for a custom return type (or examine the code of it directly). Being able to return anonymous value types would be nicer, but Java doesn't support anything like that. Actually, if I had control over Java...
  • supercat
    supercat about 10 years
    ...I'd add a few fields to Thread named tempLong1, tempLong2, tempObject1, TempObject2, etc. to minimize the number of temporary objects that need to be created purely for the purpose of being able to return more than one thing from a method. Icky, but there is no other clean solution.
  • Pacerier
    Pacerier over 9 years
    What about 3-tuples?
  • Pacerier
    Pacerier over 9 years
    @AlexeiAverchenko, Yea a cluster of 4 pairs for a Tuple-5, gross........
  • Teocali
    Teocali over 9 years
    a Pair with the value being a Pair should do the trick, no ?
  • Pacerier
    Pacerier over 9 years
    That's an ugly hack. So are you going to have a pair in a pair in a pair for 4-tuples?
  • Teocali
    Teocali over 9 years
    I think that if you need a 4-Tuples, it is a good thing to start considerate using a table instead or your own classe...
  • aem999
    aem999 over 9 years
    @RustyTheBoyRobot I don't have sufficient privilege to update the link in the comment - the link has changed to: stackoverflow.com/questions/3642452/java-n-tuple-implementat‌​ion
  • Hulk
    Hulk about 9 years
    Has there been any attempt to actually get this into standard Java? Or some project taking this a few steps further?
  • Mads Boyd-Madsen
    Mads Boyd-Madsen about 9 years
    The article above does reference a proprietary Java compiler which implements tuples. I don't think it's been considered in Standard Java though.
  • Hulk
    Hulk about 9 years
    I found a few references to this extension (named Spar/Java, it seems) in several research papers between 2001 and 2008. Would be interesting if anyone is still working on it (or why it was dropped if not).
  • Mads Boyd-Madsen
    Mads Boyd-Madsen about 9 years
    There is some activity in the Java community around this. See for instance: blogs.oracle.com/jrose/entry/tuples_in_the_vm
  • scottysseus
    scottysseus over 8 years
    While the intended purpose of this class is to facilitate the creation of custom map implementation according to the javadoc, this gets the job done nicely. +1. Also, readability isn't that big of an issue in this case.
  • Igor Konoplyanko
    Igor Konoplyanko over 8 years
    Aaaand it will be gone with jigsaw in JDK 9. I mean you still can use it, but do you really want to include javafx into your project because of this one class? :)
  • Teocali
    Teocali over 8 years
    Here I am still hoping that the "utility" part of javafx (Properties, Pair, etc.) will be migrated to the core of java, or at least to a specific module
  • yankee
    yankee almost 8 years
    If readability is a concern you could also create your own tuple like this: class Tuple extends AbstractMap.SimpleEntry {} Then you can refer to the class as Tuple.
  • Victor Zamanian
    Victor Zamanian almost 8 years
    @YagoMéndezVidal, you mean Objects.equals(other.x, this.x), etc? The method accepts two Object references as parameters, not a boolean value.
  • Yago Méndez Vidal
    Yago Méndez Vidal almost 8 years
    Yes, of course, @VictorZamanian, you're very right.
  • Dan M.
    Dan M. almost 8 years
    Tuples are not safe? That's bs. Look at C++ tuples for example (not to mention Haskell, Scala and others). If container can store values of different types, doesn't mean it is not type-safe. If anything, it's Java's limitations that prevent implementation of proper tuples.
  • Mario Reutter
    Mario Reutter almost 8 years
    @DanM. you are right. I edited my response accordingly to explicitly refer to non-generic languages only. Please consider to phrase your comments in a polite way.
  • gbmhunter
    gbmhunter over 7 years
    @n611x007, I think every tuple variant is hand-written (i.e. you can't write java code with a variable number of type parameters, at least not easily), and so it makes sense for the library writer to stop somewhere, 10 seems like a reasonable number to support most use-cases.
  • Eido95
    Eido95 over 7 years
    Note for Android developers - Android SDK has already implement genric Pair class which supported from either API 5 or API 4 (support library).
  • dsapalo
    dsapalo about 7 years
    Some of the striking characteristics of the javatuple library as described in their website -- All tuple classes are: Typesafe, Immutable, Iterable, Serializable, Comparable (implements Comparable<Tuple>), Implementing equals(...) and hashCode(), and Implementing toString(). Might be useful to know.
  • Ar5hv1r
    Ar5hv1r over 6 years
    @yankee if you're going through the trouble of creating your own class, why extend AbstractMap.SimpleEntry? Create your own type with exactly the semantics you need and your callers will expect.
  • Ar5hv1r
    Ar5hv1r over 6 years
    Worth mentioning Auto/Value here - it makes creating your own types safe and painless. It's arguably easier than using a generic Pair or Tuple type.
  • yankee
    yankee over 6 years
    @dimo414: Because SimpleEntry already implements equals, hashcode and has everything else one needs. If you want a generic Tuple then key and value maybe good names and the result might already be perfectly what you need. Of course if this is not the case then of course you are right that a custom implementation is a good idea.
  • sunofkyuss
    sunofkyuss over 6 years
    This class is not immutable. Value (one of the elements of tuple) may be changed by setValue() method.
  • Kris
    Kris about 6 years
    Sadly javafx will soon be removed from the JRE again.
  • GabrielBB
    GabrielBB over 4 years
    Java 9+ : Entry<Integer, String> pair = Map.entry(1, "a");
  • Louis Caron
    Louis Caron over 4 years
    Furthermore accessing the elements of the tuple has to be done using getKey and getValue which is not really what you mean when you want a simple two element tuple.
  • Rick-777
    Rick-777 over 4 years
    Shame about their naming, especially the (unnecessary) Unit, which has different semantics from the Unit in Kotlin, Scala etc.
  • Matt
    Matt almost 4 years
    I was excited to see that the Pair class in Apache Commons is in the org.apache.commons.lang3.tuple package, just to find out that a pair is the only type of tuple implemented :(