share
Stack OverflowDoes Java need tuples?
[+82] [23] Yuval Adam
[2009-01-19 14:37:58]
[ java data-structures syntax tuples ]
[ http://stackoverflow.com/questions/457775] [DELETED]

This question [1] got me re-thinking about something that always bothered me:

Does Java need tuples?

Do you feel the lack of them in your day-to-day work? Do you think tuples would simplify otherwise complex data structures you find yourself implementing?

@Otherside: Just you :P - Draemon
I think a critical part of the answer to N-tuples is: what would they look like in Java? Consider that when evaluating answers. - Michael Easter
[+39] [2009-01-19 14:48:22] Dan Dyer [ACCEPTED]

I don't think that Java needs tuples, but they would certainly be nice to have in certain situations.

It's not much work to write a generic Pair<A, B> class, or a Triple<A, B, C> class, which gets you most of the benefits of tuples, but the approach does not generalise to n-tuples.


(27) The Java Posse podcast often asks about Pair: if everyone is writing one, why isn't it provided? - Michael Easter
(29) To quote @James Iry, "Should Java standard lib have a Pair class? I say no. Every Java developer should just grow a Pair." - pelotom
(2) Pair<A, Pair<B,C>> - GNUnit
(1) C# 4.0 has Tuple. - Lemuel Adane
(16) I strongly disagree here : Scala (for instance) has tuples and it's a lot less code to write, less objects to create. For me, Java does need tuples. - Jean-Philippe Caruana
@Jean how do you add methods to your tuples in Java? I suppose you could figure a way to monkey-patch code into your tuple in Scala. If your data doesn't have any code relating to it then it sounds like your structure needs help or you aren't using OO (in which case pick a more appropriate language) - Bill K
(1) @BillK that's not my point, I don't need that. I need tuples when I want to return several values from a method and it comes for free with Scala for instance.See Value Object from Eric Evans's DDD before telling me I am not using OO. - Jean-Philippe Caruana
(1) @Jean My point is that if you want to return several values from a method then either A) your values are related and should be in the same object or B) your method is doing too much (one method, one concern, one return value). It's not like I don't understand what you want, I've been there before and found that by being forced to rethink my situation I was able to improve my code significantly, if Tuples had been available I would not have been forced to rethink it and would not have learned a valuable lesson. - Bill K
(1) @BillK OK, I get your point. I don't use tuples that often (in fact, I don't remember last time I did that), but I can be useful sometimes. Sometimes you just don't want to create another object just to convey 2 ou 3 related values, that would be too much boiler-plate code. I totally agree with your remark about improving my own code and my OO design though. - Jean-Philippe Caruana
Great for Co-ordinates. - Doomsknight
1
[+38] [2009-10-22 00:04:22] Scott S. McCoy

I think it does, but only in the context of supporting multiple return values. I'd like to see a method like that pike, python, perl etc copied for supporting creating a form of hidden data-structure as a return-type and linking an assignment to the invocation of said return type...as follows:

a, b = method();

And with the following, strangely obvious, return syntax:

return a, b;

And similarly it should be paired with the ability to create an array from said values, assuming there is no type mismatch. This type mismatch could easily be caught and enforced at compile time with a runtime classcastexception for when type-safety is circumvented, much like it would be today in other contexts.

Object[] results = method();

Similarly, since coersion into an array is as straight-forward as having a tuple who's all values are only a single type, it makes rather logical sense that the converse would be possible as well:

a, b = results;

Of course, this would be type-safe. Under the covers, the tuple could just be an array of Object[] much how generics are largely compile-time enforced now, and the syntax of method invocation with multiple return values could simple be translated into corresponding op-codes to take an array of object back and copy the values into the identifiers specified as capturing the result. Type-safety could be a compile-time-only enforcement, and this would avoid adding a real new language concept to the JVM and remain that multiple return values are simply syntactic sugar, and backward/forward compatibility could be upheld since the runtime byte-code would be tuple-unaware. Everything would just look like a really annoying array of object, to all those Java 6 programmers.


2
[+18] [2009-01-19 14:41:47] Ulrik Rasmussen

I think it definitely does. But tuples are just one of many language features that Java lacks, including closures and basic type inference. It's interesting to see how Scala will do in the future, as this is a JVM-language that implements a lot of the sexy language features that Java lacks.

EDIT: Of course, for tuples to be effective in Java as a native language feature, some sort of pattern matching is also required.


To be fair, Java does have basic type inference (in relation to generics), though crude might be a better description. This is one feature .NET has added of which I am really jealous. - Hank Gay
Java has closures (anonymous class instantiations). - GNUnit
3
[+11] [2011-08-11 07:40:16] Eser Aygün

Here is another argument for tuples: Hashable tuples can be used as keys for hash maps. I don't know how many times I created hash map keys by joining string representations of two or more objects. If I had tuples, I could write

Tuple key = new Tuple(keyPart1, keyPart2, ..., keyPartN);
hashMap.put(key, value);

and Java would compute the hash of the key efficiently for me.

That's why I need tuples: To combine hashes of objects efficiently.


4
[+11] [2010-04-15 12:45:03] Lohoris

Does java need to actually be python instead?

Yes it does, big time.


(2) Umm, why not just use python? I prefer Java the way it is, but I probably have different use cases than you do. - Bill K
Yep. android sdk forces you to use java. (ASE is pointless, since it does not produce applications) - Lohoris
Couldn't you use JPython with the Android SDK? - tylermac
Actually, no. Android doesn't use the JVM, so that is not possible. :( - tylermac
Java is much faster than Python, much much faster; and that's mostly due to the restrictions of the language. So, it wouldn't work for everyone to replace Java with Python. On the other hand, I guess the Python community could make a JPython port for the Android SDK. - enobayram
5
[+5] [2009-01-19 15:52:55] Uri

I've been in the same situation often enough, and I admit that in some cases I have initially done the ugly thing of using a pair or a trip. However, I generally strive to refactor these into a real object.

I don't think tuples would add much that you can't achieve with existing mechanisms (especially now that we have generics).

If Java supported Lambdas, then that would be a different thing... :)


(1) +1 for using a real object... that's what OO is about - sleske
(2) A native tuple type would be a real object. The point is not having to write repetitive code for every type of tuple that you create. You end up writing pages of code for every trivial thing, which is one of the ever-present serious failures of Java. - Glenn Maynard
6
[+3] [2009-01-19 15:12:10] Tom Hawtin - tackline

Multiple (statically-typed) return values would be useful in some circumstances (although my guess most uses would be abuses). However, a generalised tuple would, I think, be counter to the feel of Java (and would be used almost exclusively for abuse).


7
[+3] [2009-01-19 15:16:40] neu242

I might be on the wrong track here, but isn't Map.Entry [1] a tuple?

Creating a single Entry is fairly ugly, though:

public Map.Entry<String, String> tuple(String key, String value) {
    Map<String, String> map = new HashMap<String, String>();
    map.put(key, value);
    return map.entrySet().iterator().next();
}
[1] http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.Entry.html

(2) This is a pair. My guess is that the question intended N-tuples. - Michael Easter
Here's a pretty stupid N-tuple: stackoverflow.com/questions/457775/does-java-need-tuples/… - neu242
8
[+3] [2009-01-19 15:24:44] Draemon

Good question. No.

I regularly write in Java and Python, and this is exactly the sort of thing I miss when writing Java. However, what you have to remember is those two languages represent two vastly different programming paradigms. Sequences are first-class in python, and they're just another object in Java. Language-level tuples wouldn't fit in with this.

I like Python for what it is, and I like Java for what it is. While I miss features from one while programming in the other, I wouldn't want them to try to emulate each other.


(3) Do you think that language-level tuples can't fit in Java paradigm? What's the problem? - Dmitry
For the same reason that List is an interface and you don't have language-level lists; Java is a strictly typed OO language which favours the explicit over the terse. - Draemon
9
[+3] [2009-01-19 14:40:31] Alnitak

Isn't a data-only class with public fields effectively just a tuple?


(3) It's not convenient. Look, if I want to return a pair of two coordinates x and y, and that translates to typing: ^x@y, then that's ok. The other hand: ArrayList a=new ArrayList();a.add(x);a.add(y);return a; - plus: /** This method returns a list that always has length 2. first entry is x, second y. - nes1983
(2) Yes, but "return new Pair(x,y);" or even better "return new CartesianCoords(x,y);" is much better than abusing List for this purpose. - Andrzej Doyle
(1) yes, that's my point. If I want a pair of coordinates, I'll pass back a Point(x, y) object. No need for getters or setters, etc, just use it like a struct in 'C'. - Alnitak
10
[+2] [2010-04-15 16:47:23] Bill K

Very simply not necessary for an OO language--in fact, detracts from design.

If you have a method that returns two values, either they should be closely related or your method is doing more work than it should.

If they are closely related, they should be parts of an object (like a tuple). But if you are going to do that, why not create a first-class object that can have methods?

If you had tuples, you'd have to have external code to manipulate those tuples. You also wouldn't have any place to put range checking or other validations.

I've often started with a temporary class (structure) with two public variables and before the day was out had a full-fledged class with private members and methods that I missed in my original design.

I've never just left it at a pair of variables, A class seems to always be required--it just tends to work out that way.

If Java had tuples, I may not have been driven to find these design flaws and my code would be worse in every single case.

(Counterexamples welcome)


Effectively, methods' argument lists in Java are already tuples, though they are not named as such. By the same logic you use, this detracts from design, and in fact every method should take a specialized class as an argument so that this class can encapsulate things like checking that arguments are valid. - Nate C-K
I can't quite understand what you are saying--I never said parameters needed to be related, just the output. Parameters may have to come from very different concepts and are brought together by the method in order to solve a single problem, and that single problem should have a single logical output--or the output should at least be very closely related. Can you come up with an example to show me what I'm not understanding @Nate - Bill K
You're right, I did make a mistaken assumption about your intention; you never said function inputs need to be inherently associated. However, I'd like to suggest that maybe whether inputs or outputs are inherently related ought to be based on the nature of the problem itself, and that deciding that functions must necessarily map inputs to a single output is somewhat arbitrary. - Nate C-K
@Nate Can you come up with a case where a method returning two unrelated values (that absolutely didn't make sense to be in a class) couldn't be broken into two methods (each returning a value) and your codebase be better and clearer for the change? If so I'd like to undertake the challenge to refactor it into two methods--I think it would be fun. - Bill K
11
[+2] [2009-11-14 23:02:47] obiwankenobi

Yes it does! I am convinced that Java needs tuples and if it does not have it, we can define them for ourselves.

If a problem is functional, you need to program in a functional style. Object oriented style makes things unnecessarily complicated. If a function returns more than one value or structure, you need a tuple. Tuples should be immutable (as in other functional languages) to provide safe programming.

Here is a simple example of a 2-dimensional tuple class:

// pair

public class Tuple2 { public final A item1; public final B item2;

// Constructor from components
public Tuple2(A item1Init, B item2Init)
{
	item1 = item1Init;
	item2 = item2Init;
}

// Constructor from another Tuple2 with the same types:
public Tuple2(Tuple2 <A, B> anotherTuple2)
{
	item1 = anotherTuple2.item1;
	item2 = anotherTuple2.item2;
}

// No getters/setters are needed/possible because the components are public/final.

}


Of course, for triples you need to define Tuple3 in a similar way etc, unless you figure out a more generic way. If you want a more elegant functional AND object oriented programming on JVM, look at Scala. obiwankenobi - obiwankenobi
(1) you should implement hashCode() and equals() too - Hugo
12
[+1] [2010-04-15 17:08:59] Thorbjørn Ravn Andersen

You can implement most functionality of tuples with an object (nested class), but that is a bit cumbersome for one-shot usage.

A frequent reason for tuples is needing to return multiple values from a given method call. Here again, a specialized class can substitute.

Also note that you can use an array object from within a method and set its value and use that as a "return many value" holder.


(3) Agreed, Java is not intended for one-shot usage (Scripting)--it's intended to be readable and maintainable, it prefers explicit over implicit--visible over hidden. There are scripting languages based (both loosely and closely) on Java if brevity is your goal. - Bill K
Tuples are also a major feature of ML, a language that arguably has a more expressive (and type-safe) type system than Java. Often coding up special classes for what are, in fact, one-off uses, just clutters your code and makes it harder to read and maintain. - Nate C-K
@Nate, in that case consider creating Tuple2<T1, T2> and Tuple3<T1, T2, T3>. - Thorbjørn Ravn Andersen
I could. But the whole point is that such types are so basic that they should be part of the standard library in the first place. - Nate C-K
13
[+1] [2009-07-22 14:17:23] community_owned

What is the benefit of having tuples without introducing pattern matching on invocation?

Therefore, the question become: «Does Java need tuples and pattern-matching on invocations?»

And subsequently, is it even possible for java to support pattern matching?


Or, more to the point if you're familiar with pattern-matching: why are we still using a language that doesn't offer pattern-matching? - Nate C-K
14
[+1] [2009-01-19 14:43:07] cletus

Anyone who has used JPA and Object arrays to return multiple items for a JPQL query will tell you Java needs an equivalent of the C# var type.


(1) Actually, the var "type" in C# is not allowed as return or parameter type; it is for inferring types only on local variables. - Rafa Castaneda
15
[+1] [2009-01-19 15:02:42] Bombe

No, it doesn’t. In my class library here at work I do have a class Pair but I don’t use it very often and only for internal purposes, i.e. it’s never exposed in a public interface.


16
[0] [2009-01-19 14:43:39] Steve Losh

What I really miss is some type of list that's not mind-numbingly annoying to work with. If I could declare and use an ArrayList of different types of objects without a metric ass-ton of casting I'd be much happier.

I don't think tuples (in the Python, same-as-lists-but-immutable sense) are really critical though.


can't you use the generic ArrayList<type> to avoid casting issues? - bobwah
What if I want an ArrayList of some Integers and some Strings? I can use an ArrayList<Object> but then I need to cast on the way out. - Steve Losh
(1) The solution is to not use a statically typed language like Java of course. But even then I'm hard pressed to find an example where it would be a good idea to store strings and integers in the same list! - Wim Coenen
(1) Maybe a HashMap would be a better example. In Python I can say: person = { 'name': 'Steve', 'last_login': datetime.datetime.now(), 'karma': 722 }; print person['name'], person['last_login'].day, person['karma']*10; That'd be a lot of casts in Java. - Steve Losh
(1) Person p = new Person("Steve", System.currentTimeMillis(), 722); System.out.println(p.getName(), p.getLastLogin(), p.getKarma() * 10); - I don’t see no casts here! :) - Bombe
@Bombe You forgot to include the contents of Person.java, but that might not fit in one of these comments. - Steve Losh
The comment by @Steve Losh is not in any way, shape or form OO. There is no really good way to interact with person--no way to know what the contents could be. The one by @Bombe is completely clear and obvious, however it wouldn't be very easy to use in a scripting scenario where you are just throwing out a little spat of one-off code for a shell script. Java has a usage scenario that is different from most of the dynamic languages... It's made to be readable, usable and maintainable, not minimalistic. - Bill K
17
[0] [2010-05-18 23:10:21] Jekke

Well, I found this question by Googling "tuples Java" because I needed them. I like the tuple-less solution I coded up far less than what I could have done had they been present.


18
[0] [2010-07-12 11:35:20] Peter Gwiazda

I'd rather see Case Classes (from Scala) in Java than tuples. Case class is something like

public class MyClass {

    private Integer intField;
    private String stringField;
    private Date dateField;

    public MyClass(Integer intField, String stringField, Date dateField) {
        this.intField = intField;
        this.stringField = stringField;
        this.dateField = dateField;
    }

    public Date getDateField() {
        return dateField;
    }

    public void setDateField(Date dateField) {
        this.dateField = dateField;
    }

    public Integer getIntField() {
        return intField;
    }

    public void setIntField(Integer intField) {
        this.intField = intField;
    }

    public String getStringField() {
        return stringField;
    }

    public void setStringField(String stringField) {
        this.stringField = stringField;
    }

}

but you'd write it like this

public case class Myclass(Integer intField, String stringField, Date dateField);

Additionally in Scala pattern matching is done on case classes : http://www.scala-lang.org/node/107


I think we need both. The problem with only having case classes is that you attach more information to the type than necessary (the constructor name), when what you really need is just a tuple. This destroys generality, and makes it more difficult to implement, for instance, polymorphic zip/unzip methods. Syntactic sugar for tuples that converted them to a conventional set of predefined polymorphic case class constructors could probably solve this. - Ulrik Rasmussen
19
[0] [2011-03-29 16:28:24] Berlin Brown

Here is another tuple, pair approach with generics:

public class TuplePair<X, Y, Z> {

    private final X first;
    private final Y second;
    private final Z third;

    public TuplePair(X f, Y s, Z z) {
        first  = f;
        second = s;
        third  = z;
    }
    ...
    ...
}

20
[0] [2011-06-21 07:36:53] SonyAD

Of course you need couples and touples.

How else are you going to represent vertices in 2D and 3D without using per coordinate arrays (2 or 3 parallel arrays - very, very ugly and unsafe) or...

rewriting yourself what should already have been there for you and actually was...

until they deprecated it.


21
[0] [2011-10-28 09:16:25] Stefan

I always just use things like this. Existing, java.util, tested, reusable, just nice.

Map.Entry<String, Boolean> tuple = new AbstractMap.SimpleEntry<String, Boolean>("test",false);

And things also work more complex like: Map.Entry<List<String>, Boolean> or whatever...


22
[-2] [2009-01-19 15:03:27] gizmo

To my standpoint, no, Java does not need tuples. Wait, let me refine it. It would be a BAD idea to implement tuples in Java.

Why? Because of Java way of thinking. Nearly everything in Java is there to prevent runtime errors: statically strong typing, explicit variable declaration, single inheritance, generics, exceptions and so on.
This is the strongest point of Java (with its huge library), and that's why java gains so much popularity in the industry world.

Tuples means implicitly adding dynamic typing and inference, which is completely at the oposite of Java's philosophy.

Not that tuples are bad, I use them happily in other languages, they're just inappropriate for Java.

EDIT: To explain my point about dynamic typing, as said in the comment, I was thinking about an unknown set of return elements.
Anyway, how would we grab the tuple? Using a

val1, val2 = obj.method()

could be fine, but what if you want to use the result as a parameter of another method?


(18) A don't see why tuples imply dynamic typing. - Tom Hawtin - tackline
You're right, it depends to how far you want to go with tuple as return. I was thinking about an unknown set of elements in the return type. But if you restrict it to a given set, you remove that issue. - gizmo
(9) -1: Statically typed n-tuples are already part of the standard library of F#, Haskell, Scala, and OCaml. Its trivial to implement as a Tuple<t, u> or Tuple<t, u, v> class in Java, however its not very pretty given Java doesn't support type inference or variable decomposition. - Juliet
(4) I disagree. Why would tuples have to be dynamic? - Uri
You ask "but what if you want to use the result as a parameter of another method". Clearly, you should be able to do "val = obj.mehod()" as well, with "val" now having a (static and generic) Tuple type. Then you can write "anotherMethod(obj.method())" if "anotherMethod" accepts a parameter that can be unified with the return type of "obj.method()". IMO, you should look at F#, Haskell and OCaml for a good idiom of tuple values, not at Python. - harms
(1) What would be wrong with Tuple<K, K, V>? - Thorbjørn Ravn Andersen
23