Tuple (unmodifiable ordered list of heterogeneous elements) support in Java

11,477

Solution 1

The "Java way" is to define use-specific classes rather than these sorts of lightweight semi-class types. If you think about it, a tuple is really just a simplified struct; the Java folks would prefer you to just go ahead and create the struct.

This perspective is changing a bit, especially in Java 8 with its lambdas (which put pressure on the JDK to provide generic Function-type interfaces rather than use-case-specific interfaces like FooCallback). But it's still a fairly strong mindset for a lot of Java developers, and there's some sense to it. Java is a very statically typed language; a tuple is somewhere between static typing and dynamic typing, in that there's nothing in the type system to prevent you from thinking this (int, String) that represents a customer ID and name is actually an (int, String) representing an order ID and its description.

See, for instance, this discussion ("Tuples for n >= 2") on the issue within the Guava project. Granted, that's not official; but it's a good representation of the Java mindset.

Solution 2

There is a nice library called javatuples. It defines generic tuple types for arities from 1(Unit) to 10(Decade) and all essential methods like equals, hashCode, toString and even compareTo.

Official site: http://www.javatuples.org/
Maven dependency:

<dependency>
    <groupId>org.javatuples</groupId>
    <artifactId>javatuples</artifactId>
    <version>[version]</version>
    <scope>compile</scope>
</dependency>

(at the moment latest version is 1.2)

Solution 3

It has:

Collections.unmodifiableList(yourList)

will do the trick.

I think that the versatility of the JCF makes the existence of explicit tuple datastructures unnecessary.

I assume that by tuple you mean an ordered immutable list of elements (according to the wikipedia definition).

As for the 3rd party library my power search on google yielded this, this and of course this.

Solution 4

There is a type in the Java runtime and it is called Entry. This is an interface inside Map and there are simple implementation of it inside AbstractMap.

http://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html

http://docs.oracle.com/javase/7/docs/api/java/util/AbstractMap.SimpleEntry.html

You can use it as a tuple for two members, you can even apply generics. I would think hard what I did wrong if ever I needed more elements than two. Probably worth it own class then.

Solution 5

A colleague and I were discussing this a few weeks ago. The only solution I could come up with was to internally store the values in a Map<Class, Object> and have some accessor method getValue(Class). Otherwise, how do you access the values in your tuple? You can't have a generic Tuple class with methods for each member, e.g. getInteger, getString, etc because those methods would not be known until runtime, when you create the tuple. This also means you could never have two members with the same type -- how would you be able to write such a class so that at runtime, it knew which object to retrieve?

Share:
11,477
Oleksandr Karaberov
Author by

Oleksandr Karaberov

Updated on June 15, 2022

Comments

  • Oleksandr Karaberov
    Oleksandr Karaberov almost 2 years

    I wonder why Java doesn't have a tuple data structure implementation in its standard library. For instance C++ has a very good implementation of this fixed-size collection of heterogeneous values. The same in Haskell. In Java I only know javatuples and some support in Functional Java library via Product (P1 - P8) types. I wonder why tuple or at least pair not in standard library at all? Even Android SDK developers added their own implementation of 2-tuple (pair).

  • Paul Bellora
    Paul Bellora over 11 years
    How does this answer the question?
  • José Roberto Araújo Júnior
    José Roberto Araújo Júnior over 11 years
    @PaulBellora tuple = unmodifiable list
  • Oleksandr Karaberov
    Oleksandr Karaberov over 11 years
    By tuple I mean just a product algebraic data type. And as far as I know in imperative languages tuples sometimes implemented as mutable data structures
  • John B
    John B over 11 years
    FYI, Guava's ImmutableList is considered safer than unmodifiableList as unmodifiableList can still result in a ConcurrentModificationException
  • Paul Bellora
    Paul Bellora over 11 years
    @JoséRobertoAraújoJúnior Understood - I read the OP's use of "heterogeneous" to mean something like Tuple2<String, Integer> etc.
  • rtheunissen
    rtheunissen over 11 years
    How would Generics not solve this? Tuple<String, JComponent> tup = new Tuple<>(); ... panel.add(tup.getLast()); label.setText(tup.getFirst()); This is obviously a forced size of 2 tuple but it's easy enough to have an Object array underneath and have the programmer be responsible for casting. In all my years I've never found a situation where I've needed a tuple data structure where an easy alternative wasn't available.
  • Adam Arold
    Adam Arold over 11 years
    I know about ImmutableList but it is not part of the JCF I was talking about. Thanks for pointing it out though.
  • Thorn G
    Thorn G over 11 years
    So when you want more than 2 elements, what do you do? You can't write getSecond, getThird, etc. You might as well just have Object[] at that point.
  • rtheunissen
    rtheunissen over 11 years
    Tuple structures of more than 2 more 3 elements would be a glorified Object [], where instead of getFirst() getSecond() you would have get(index), which is hardly any different to an Object [] or List<Object>. Quite often it might be nice to pair two types together, which for the most part becomes a Map.
  • Display Name
    Display Name almost 11 years
    Then why don't you create a class for every tuple of arity 1? There's nothing in the type system to prevent you from thinking this int that represents a customer ID is actually an int representing an order ID.
  • Display Name
    Display Name almost 11 years
    BTW, it's very easy to spot it by searching in google "java tuples".
  • yshavit
    yshavit almost 11 years
    @SargeBorsch In short, because Java isn't well designed for that pattern. Classes have overhead in performance, complexity (is it null?) and reflection (not a drop-in replacemtnt for an int). If you have to pay that cost anyway, you may as well do it right; if you don't, it's more of a balancing act. But to your point, I actually wish that Java did have something like Haskell's newtype, which would let you create a CustomerId which is a type-safe int.
  • yshavit
    yshavit almost 11 years
    Yup, Java draws a line in the sand between primitives and classes. No avoiding it.
  • Display Name
    Display Name almost 11 years
    But all is not lost, there is some interesting workarounds in Scala. (unified type system, specialization, ...)
  • ymajoros
    ymajoros almost 9 years
    @SargeBorsch I do just that wherever I can. Using id's instead of objects isn't the common path in most of my projects anyway.
  • Display Name
    Display Name over 8 years
    In statically&strongly typed languages, tuple is more than just a fixed size list, because its type does contain information about the types of its elements. So N-element tuple has N type parameters. Lists have only one type parameter, that means, each list element has the same (compile-time) type.
  • Adam Arold
    Adam Arold over 8 years
    There are a number of concepts which can be implemented in java but in a handicapped version. A good example might be a Trait or a Mixin. Therefore java developers are usually only implementing what is necessary. As you can see in my answer I assumed something which is based on the wikipedia definition.
  • BobDoolittle
    BobDoolittle over 5 years
    I wish the "this dicussion" link still worked, I'm curious. I have the same intuition. Tuples like Pair feel like a concept that wandered out of Python and strayed into Java in a drunken stupor. There should be a better semantic binding between the elements so you know why they belong together and what their relationship is. Bob and Teri are a married couple, not just a Pair of people with an unknown relationship because their Author was too lazy to define marriage. Otherwise they could just be next-door neighbors, you wouldn't know.
  • yshavit
    yshavit over 5 years
    @BobDoolittle I found the page on the wayback machine and updated the link. Thanks for the nudge! That said, there isn't anything on that page that you didn't already know. :-) I originally posted this question a while ago, but I think I was mostly trying to cite a well-adopted project to say that this isn't just my opinion, it's shared by others.