Using Pairs or 2-tuples in Java
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;
}
}
syker
Updated on October 30, 2021Comments
-
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 over 13 yearsI think it would be better to declare
x
andy
aspublic final
and get rid of those getters. -
Anoyz almost 12 yearsThat is not a tuple. It only hold pairs (tuples of length 2).
-
Kjellski over 11 yearsI'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 almost 11 yearsThe implementation provided by Apache Commons fulfills exactly what I needed. I am happy to have a working implementation.
-
athabaska over 10 yearsIf x or y is String, equals method will be not be working ok.
-
djechlin over 10 yearsLess readable. If I saw this in code I'd wonder where the map is.
-
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 over 10 yearsDoes it only cover tuples to 10-tuples?
-
n611x007 over 10 yearscould you paste the relevant part here, before groups close down or anything? SO encourages copying relevant information to on-site.
-
n611x007 over 10 yearsWell, the question seems to be wrong about tuples. Pairs != Tuples. Tuples are n-length, ie. any length.
-
n611x007 over 10 yearsAh, the question is just wrong. Are these ordered? Can have duplicate elements? What about a tuple? ;)
-
n611x007 over 10 yearsThis too suffers from the question's wrong assumption that tuples should be Pairs.... tuples are of any length, not just 2.
-
Alexei Averchenko over 10 years@naxa Better something than nothing. Also, you can nest pairs.
-
rhgb over 10 years@naxa please re-check the question description and you may found a
Pair
is exactly what he need. -
n611x007 over 10 yearsyou 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 over 10 yearsThis is the actual solution as the one accepted will fail in the
Hashtable
(as requested in the question) since thehasCode()
andequals()
of 2 same couples will differ. -
Yago Méndez Vidal over 10 yearsAs athabaska noted, just substitute the last line of
equals()
toreturn 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 over 10 yearsThis 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()
andhashCode()
must be overriden. -
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 over 10 years@YagoMéndezVidal good point, this was generated in Eclipse...
-
RustyTheBoyRobot about 10 years@aem999 - The question you link to has been deleted.
-
thisdotnull about 10 years@RustyTheBoyRobot updated link stackoverflow.com/questions/3642452/java-n-tuple-implementation
-
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 meanTuple
is not a good name for classes with hardcoded number of types in languages with "real" generic types. -
supercat about 10 yearsIf 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-indouble[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 about 10 years...I'd add a few fields to
Thread
namedtempLong1
,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 over 9 yearsWhat about 3-tuples?
-
Pacerier over 9 years@AlexeiAverchenko, Yea a cluster of 4 pairs for a Tuple-5, gross........
-
Teocali over 9 yearsa Pair with the value being a Pair should do the trick, no ?
-
Pacerier over 9 yearsThat's an ugly hack. So are you going to have a pair in a pair in a pair for 4-tuples?
-
Teocali over 9 yearsI 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 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-implementation
-
Hulk about 9 yearsHas there been any attempt to actually get this into standard Java? Or some project taking this a few steps further?
-
Mads Boyd-Madsen about 9 yearsThe article above does reference a proprietary Java compiler which implements tuples. I don't think it's been considered in Standard Java though.
-
Hulk about 9 yearsI 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 about 9 yearsThere is some activity in the Java community around this. See for instance: blogs.oracle.com/jrose/entry/tuples_in_the_vm
-
scottysseus over 8 yearsWhile 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 over 8 yearsAaaand 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 over 8 yearsHere 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 almost 8 yearsIf 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 asTuple
. -
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 almost 8 yearsYes, of course, @VictorZamanian, you're very right.
-
Dan M. almost 8 yearsTuples 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 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 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 over 7 yearsNote for Android developers - Android SDK has already implement genric Pair class which supported from either API 5 or API 4 (support library).
-
dsapalo about 7 yearsSome 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 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 over 6 yearsWorth mentioning Auto/Value here - it makes creating your own types safe and painless. It's arguably easier than using a generic
Pair
orTuple
type. -
yankee over 6 years@dimo414: Because SimpleEntry already implements equals, hashcode and has everything else one needs. If you want a generic
Tuple
thenkey
andvalue
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 over 6 yearsThis class is not immutable. Value (one of the elements of tuple) may be changed by setValue() method.
-
Kris about 6 yearsSadly javafx will soon be removed from the JRE again.
-
GabrielBB over 4 yearsJava 9+ : Entry<Integer, String> pair = Map.entry(1, "a");
-
Louis Caron over 4 yearsFurthermore accessing the elements of the tuple has to be done using
getKey
andgetValue
which is not really what you mean when you want a simple two element tuple. -
Rick-777 over 4 yearsShame about their naming, especially the (unnecessary)
Unit
, which has different semantics from theUnit
in Kotlin, Scala etc. -
Matt almost 4 yearsI was excited to see that the
Pair
class in Apache Commons is in theorg.apache.commons.lang3.tuple
package, just to find out that a pair is the only type of tuple implemented :(