Java Tuple

Final UpdateThe latest code is at http://adventuresinsoftware.com/blog/?p=546. The javatuple.com site is going off-line.

Update I've created a new version of this Java Tuple library. It can be found at http://javatuple.com. The new version uses generics for type safety. It also has extractor methods. If you use Java 1.4 or earlier, or you just prefer the previous version, please read on. Otherwise, visit javatuple.com.

Thanks.

I don't know how many times I've needed a hash map with a compound key, but it seems to come up often. Every time, I am faced with the same question: do I really want to define a class for this key?It's seems like such a simple thing at first. Just a class with a few members. But then you have to initialize those members in the constructor. And then you need to write equals(). And don't forget hashCode(). Sometimes I'm tempted to create a concatenated string to get around the extra baggage. But that would be a hack.To solve this problem, I finally decided to create a Tuple class. A tuple is a an ordered collection of heterogeneous elements. Compare this to a vector, which is homogeneous. The type of a tuple is defined by the number and type of its elements.Examples of tuples that naturally occur in software are parameter lists and database rows. Both of these things have a fixed, finite number of elements that must occur in a certain order. All rows in a table have the same number and types of columns, but one column can have a different type from another. Some languages treat tuples as native data types, but not Java.My Tuple class comes in two pieces. The base class implements all of the comparison behavior. The concrete class lets you build a generic tuple.

package com.adventuresinsoftware.tuple;import java.util.ArrayList;import java.util.Iterator;public abstract class BaseTuple implements Comparable {    // Ordered collection of elements.    ArrayList elements = new ArrayList();    // Strings used to display the tuple.    String open;    String separator;    String close;    // Initialize the strings for this tuple type.    protected BaseTuple(String open, String separator, String close) {        this.open = open;        this.separator = separator;        this.close = close;    }    // Add elements to the tuple. Supports dot-chaining.    protected BaseTuple addElement(Object o) {        elements.add(o);        return this;    }    protected BaseTuple addElement(int i) {        return addElement(new Integer(i));    }    // Compare two tuples. All elements must be equal.    public boolean equals(Object obj) {        if (obj == null)            return false;        if (!(obj instanceof BaseTuple))            return false;        BaseTuple that = (BaseTuple) obj;        if (that.elements.size() != this.elements.size())            return false;        for (int i = 0; i < elements.size(); ++i) {            if (!that.elements.get(i).equals(this.elements.get(i)))                return false;        }        return true;    }    // Calculate a hash code based on the hash of each element.    public int hashCode() {        int result = 0;        Iterator it = elements.iterator();        while (it.hasNext()) {            result = result * 37 + it.next().hashCode();        }        return result;    }    // Display the tuple using the open, separator, and close    // specified in the constructor.    public String toString() {        StringBuffer result = new StringBuffer(open);        Iterator it = elements.iterator();        while (it.hasNext()) {            result.append(it.next());            if (it.hasNext())                result.append(separator);        }        return result.append(close).toString();    }    // Order by the most significant element first.    // The tuples must agree in size and type.    public int compareTo(Object o) {        BaseTuple that = (BaseTuple) o;        for (int i = 0; i < elements.size(); ++i) {            int compare = ((Comparable) this.elements.get(i))                .compareTo((Comparable) that.elements.get(i));            if (compare != 0)                return compare;        }        return 0;    }}
package com.adventuresinsoftware.tuple;public class Tuple extends BaseTuple {    // Display a coma-separated list of elements.    public Tuple() {        super("(", ", ", ")");    }    // Add generic elements to the tuple.    // Supports dot-chaining.    public Tuple add(Object o) {        super.addElement(o);        return this;    }    public Tuple add(int i) {        super.addElement(i);        return this;    }}

To use a Tuple as a compound HashMap key, just construct one in place using dot-chaining.

    public void testTupleHashMap() {        Map population = new HashMap();        population.put(            new Tuple().add("TX").add("Dallas"),            new Integer(1213825));        population.put(            new Tuple().add("TX").add("Fort Worth"),            new Integer(624067));        population.put(            new Tuple().add("IL").add("Springfield"),            new Integer(203564));        population.put(            new Tuple().add("NM").add("Albuquerque"),            new Integer(494236));        assertEquals(new Integer(624067), population.get(            new Tuple().add("TX").add("Fort Worth")));        assertNull(population.get(            new Tuple().add("NM").add("Roswell")));        assertNull(population.get(            new Tuple().add("NJ").add("Springfield")));    }

The Tuple class has a useful toString method.

    public void testTupleToString() {        Tuple tuple = new Tuple().add("MLB").add(1);        assertEquals( "(MLB, 1)", tuple.toString() );    }

And if you want to create your own strictly typed tuples, you can declare your own derived class.

package com.adventuresinsoftware.tuple;public class Version extends BaseTuple {    // A version is a tuple of 4 integers separated by periods.    public Version(int major, int minor, int release, int qfe) {        super("", ".", "");        addElement(major).addElement(minor).addElement(release).addElement(qfe);    }}
    public void testVersion() {        Version v1 = new Version(2,0,2,3425);        Version v2 = new Version(2,1,0,241);        assertEquals("2.0.2.3425", v1.toString());        assertEquals("2.1.0.241", v2.toString());        assertTrue("Version 2.1.0.241 > 2.0.2.3425", v2.compareTo(v1) > 0);    }

Enjoy!

43 Responses to “Java Tuple”

  1. Johnicholas Hines Says:

    This is really cool!

    Two questions:
    1. Is the magic number 37 important? Is it possible to replace the "iterate and hash" procedure with something like elements.HashCode()?
    2. How do you get, say, the third field from a tuple? tuple.elements.get(3)?

    Anyway, I will be using your code; thank you very much!

  2. Michael L Perry Says:

    The magic number is best when prime. 37 is just a nice easy prime to remember.

    This particular tuple implementation is not designed for random access. The goal here was just to create a multi-valued key. But if you find you need that functionality, it is easy to add. The drawback is that you will have to cast from Object to the expected type. I'm not sure if generics will improve matters any, but you can try.

  3. Irfan Jamadar Says:

    Thought of a wee enhancement to the single maker.
    Basically I wanted to call Tuple with a varargs/array of objects and have it smartly construct the appropriate 'N Tuple' instance.
    So I changed the Tuple method to be:

    @SuppressWarnings("unchecked")
    public static <T extends Tuple, T1> T from(T1 m1) {
    if (m1 != null && m1.getClass().isArray())
    {
    Object[] arr = (Object[]) m1;
    for (Method meth : Tuple.class.getMethods())
    if (meth.getName().equals("from") && meth.getParameterTypes().length == arr.length)
    try
    {
    return (T) meth.invoke(Tuple.class, arr);
    }
    catch (Throwable t)
    {
    t.printStackTrace();
    }

    }
    return (T) new Single(m1);
    }

    Thus I can invoke it with:

    Triple<Integer, String, Tuple> tuple = FlyweightTuple.get(Triple.class, null, "Atom", Tuple.from(new String[]{"a", "b"}));
    System.out.println(tuple);

    And find that the third item is indeed a Tuple Pair (and not a single Object[]).

    I can course still use it per normal i.e. Single singleTuple = Tuple.from("Hey");

    Hope this helps :o)

  4. Irfan Jamadar Says:

    Slightly better version of above (allowing proper component type coming back) :

    public static Single from(T1 m1) {
    return new Single(m1);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Tuple, T1> T from(T1[] m1) {
    if (m1 != null)
    {
    Object[] arr = (Object[]) m1;
    for (Method meth : Tuple.class.getMethods())
    if (meth.getName().equals("from") && meth.getParameterTypes().length == arr.length)
    try
    {
    return (T) meth.invoke(Tuple.class, arr);
    }
    catch (Throwable t)
    {
    throw new IllegalStateException("Unable to invoke Tuple maker.", t);
    }
    }

    return (T) Tuple.from(null);
    }

  5. Irfan Jamadar Says:

    Also have Tuple implement the Iterator interface i.e.:

    Iterable

    And then include the following (in Tuple class):

    public Iterator iterator ()
    {
    return new Itr(this);
    }

    private class Itr implements Iterator
    {
    // Index of element to be returned by subsequent call to next.
    private Tuple cursor;

    private boolean atEnd;

    public Itr (Tuple start)
    {
    cursor = start;
    atEnd = false;
    }

    public boolean hasNext()
    {
    return !atEnd;
    }

    public First next()
    {
    if (!hasNext())
    throw new NoSuchElementException();

    Variable var = new Variable();
    Object r = cursor.extract(var);
    if (End.class.isAssignableFrom(r.getClass()))
    atEnd = true;
    else
    {
    @SuppressWarnings("unchecked")
    Tuple r2 = (Tuple)r;
    cursor = r2;
    }

    return var.get();
    }

    public void remove()
    {
    throw new IllegalStateException("Remove operation not supported");
    }
    }

    You can then do, for example:

    for (String item : tuple)
    System.out.println(" value = "+ item);

    Naturally, if mixed types are in the tuple then you will have to use the super type common to all elements (for item).

  6. Michael L Perry Says:

    Cool changes, Irfan. It's not the way that I use tuples, but it's cool nonetheless.

    To my mathematical background, a tuple is not a collection. It's size cannot vary, and if all of it's elements are the same type, well that's just a coincidence.

    The type of a tuple is based on the number and types of its members. That's the reason I switched to the generic version. It demonstrates that Java's generics, while they have some problems, are powerful enough to infer aggregate types out of simple ones.

  7. Steve Says:

    Noticed a bug in Tuple.compareTo when comparing identical cases. The problem is that Tuple.compareTo doesn't check for "End", so if you have identical Tuples it'll throw an exception when it hits end. The solution is to check to see if you've reached the End in compareTo. See the end of this message for a possible solution.

    This test case will result in "java.lang.ClassCastException: com.mallardsoft.tuple.End cannot be cast to java.lang.Comparable":

    public void testTupleEquality() {
    Triple t=new Triple("my", 123, "fake");
    Triple t2=new Triple("my", 123, "fake");
    try
    {
    System.out.println("Comparison: " + t.compareTo(t2));
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    }

    ---- My fix:
    // Order by the most significant element first.
    // The tuples must agree in size and type.
    public int compareTo(Tuple that) {
    int compare = ((Comparable) this.first).compareTo(that.first);
    if (compare != 0)
    return compare;
    else {
    if (this.rest instanceof End && that.rest instanceof End) {
    return 0;
    } else
    return ((Comparable) this.rest).compareTo(that.rest);
    }
    }

  8. Alex Says:

    What license is JavaTuples under?

  9. Michael L Perry Says:

    The code is licensed under Creative Commons Attribution 3.0. Feel free to use it for any project, commercial or otherwise. Modify it to meet your needs. Just please attribute the source.

  10. Michael L Perry Says:

    Thanks, Steve. I applied a slightly different fix.

    package com.mallardsoft.tuple;
    
    public class End implements SeparatedAppender, Comparable<End> {
    
    	private static End instance = new End();
    
    	public static End getInstance() {
    		return instance;
    	}
    
    	private End() { }
    
    	public void appendString(StringBuffer buffer, String separator) {
    	}
    
    	@Override
    	public int compareTo(End o) {
    		return 0;
    	}
    
    }
    

    I made End implement Comparable and always return 0. Every End is equal to every other End.

    One caveat to this is that comparing tuples of different sizes will produce a ClassCastException when the runtime tries to cast a Tuple to End or End to Tuple in order to call the last compareTo. But if you let the compiler verify your types for you, then this will be caught early. Your unit test uses Tuple as a raw type, so the compiler can't help you. But the following change retains type information:

    Triple<String, Integer, String> t = Tuple.from("my", 123, "fake");
    Triple<String, Integer, String> t2 = Tuple.from("my", 123, "fake");
    

  11. Peter Niederwieser Says:

    Great to see a tuple implementation for Java. How about including the license in the JAR?

  12. Karl Isenberg Says:

    You should be able to remove the Comparable cast in the compareTo method if you change the class definition to:

    public class Tuple<First extends Comparable, Rest extends Comparable> implements SeparatedAppender,
    Comparable<Tuple> {

    And yes, you should probably include the license in the JAR and also add JavaDoc headers for all of the classes that says they are all part of the same package and under the same license.

  13. Karl Isenberg Says:

    hmm, it ate some of my code.
    How about:
    public class Tuple<First extends Comparable, Rest extends Comparable> implements SeparatedAppender,
    Comparable<Tuple> {

  14. Karl Isenberg Says:

    nope...
    Third times the charm?

    public class Tuple<First extends Comparable<First>, Rest extends Comparable<Rest>> implements SeparatedAppender,
    Comparable<Tuple<First, Rest>> {

  15. Michael L Perry Says:

    Thanks, Karl. What made it through was just enough to get your point across. I've updated the source code with your suggestion. It works like a champ.

    I've included the license in the zip file and in the header of each source file. Please feel free to reuse, redistribute, modify, and enjoy!

  16. Kamil Páral Says:

    I wanted to use javatuple in my opensource project, but as I see, I can't, because of the CC-BY license. First of all, CC licenses are not intended to be used for software:
    http://wiki.creativecommons.org/Frequently_Asked_Questions#Can_I_use_a_Creative_Commons_license_for_software.3F
    Also, CC-BY (at least 2.0) is incompatible with GNU GPL:
    http://www.gnu.org/licenses/license-list.html#OtherLicenses

    As a second remark, it would be very convenient if you provide at least an ant build script.

    And it is very unfortunate that you don't even provide your email so people can hardly contact you (using comments in some blog forum is really pretty useless).

  17. Michael L Perry Says:

    Very good points, Kamil. I'll look into the license issue and tell you what I decide to change it to. I did not realize that CC was not recommended for software, or that it was incompatible with GPL.

    It is my intent that you should be able to use Java Tuple for any project, open source or otherwise. For that reason, I will not be using GPL. I may, however, choose LGPL.

    I can certainly provide an Ant build script. I build with Eclipse, so I have no need for Ant myself. Still, I suspect that the script will be simple.

    I prefer an open conversation via comment posts, so I encourage people to contact me that way. For this reason, I have posted this message both as a comment and as an email.

    That said, if you would prefer to contact me directly rather than posting, you can reach me at mperry at aventures in software dot com. I will reply to direct email in kind, not by posting a comment.

    Thanks for your comments, and I'll let you know when I've made a licensing decision.

  18. Michael L Perry Says:

    Thanks to Kamil's feedback, I've selected a FreeBSD license and added an Ant script. You can find the updates on http://javatuple.com.

  19. Kamil Páral Says:

    Thank you very much.

  20. Kamil Páral Says:

    The licence text appended after class description destroyed some of the javadocs for that class. See Tuple class. The license text is now part of description of the second parameter.

  21. Michael L Perry Says:

    Problem solved. Thanks again.

  22. DataSurfer Says:

    [code]Tuple<Double,Tuple<Integer,Tuple>> t1 =
    Tuple.from("c").prepend(2).prepend(2.3);[/code]

    [quote]Although this method is more flexible, it is more difficult syntax. The elements must be added to the tuple in reverse order. And the type is expressed in its fully exploded form. If you must use this syntax, then take full advantage of Eclipse's refactoring tools to generate type declarations.[/quote]

    Couldn't you use varargs to simplify this?

    Something ala:
    [code] public static Tuple from(Comparable... members) {
    Comparable lastMember = members[members.length - 1];
    Tuple tuple;
    if (lastMember instanceof Byte) tuple = Tuple.from(( Byte) lastMember);
    else if (lastMember instanceof Short) tuple = Tuple.from(( Short) lastMember);
    else if (lastMember instanceof Integer) tuple = Tuple.from(( Integer) lastMember);
    else if (lastMember instanceof Long) tuple = Tuple.from(( Long) lastMember);
    else if (lastMember instanceof Float) tuple = Tuple.from(( Float) lastMember);
    else if (lastMember instanceof Double) tuple = Tuple.from(( Double) lastMember);
    else if (lastMember instanceof Boolean) tuple = Tuple.from(( Boolean) lastMember);
    else if (lastMember instanceof Character) tuple = Tuple.from(( Character) lastMember);
    else if (lastMember instanceof BigDecimal) tuple = Tuple.from((BigDecimal) lastMember);
    else if (lastMember instanceof BigInteger) tuple = Tuple.from((BigInteger) lastMember);
    else if (lastMember instanceof String) tuple = Tuple.from(( String) lastMember);
    else if (lastMember instanceof Enum) tuple = Tuple.from(( Enum) lastMember);
    else tuple = Tuple.from( lastMember);

    if (members.length > 1) {
    for (int i = members.length - 2; i > 0; i--) {
    if (members[i] instanceof Byte) tuple = tuple.prepend(( Byte) members[i]);
    else if (members[i] instanceof Short) tuple = tuple.prepend(( Short) members[i]);
    else if (members[i] instanceof Integer) tuple = tuple.prepend(( Integer) members[i]);
    else if (members[i] instanceof Long) tuple = tuple.prepend(( Long) members[i]);
    else if (members[i] instanceof Float) tuple = tuple.prepend(( Float) members[i]);
    else if (members[i] instanceof Double) tuple = tuple.prepend(( Double) members[i]);
    else if (members[i] instanceof Boolean) tuple = tuple.prepend(( Boolean) members[i]);
    else if (members[i] instanceof Character) tuple = tuple.prepend(( Character) members[i]);
    else if (members[i] instanceof BigDecimal) tuple = tuple.prepend((BigDecimal) members[i]);
    else if (members[i] instanceof BigInteger) tuple = tuple.prepend((BigInteger) members[i]);
    else if (members[i] instanceof String) tuple = tuple.prepend(( String) members[i]);
    else if (members[i] instanceof Enum) tuple = tuple.prepend(( Enum) members[i]);
    else tuple = tuple.prepend( members[i]);
    }
    }
    return tuple;
    }[/code]

  23. Michael L Perry Says:

    Sorry about the code formatting. I should probably find a more code friendly comments plug-in for Wordpress.

    The problem with the varargs idea is that it works against Java's generics. The compiler cannot determine the actual type of the Tuple produced. Since Java's generics are compile-time only, there is no problem at run time. But I'm trying to be as compiler-friendly as possible with this library.

  24. DataSurfer Says:

    I intended for the return type to be Tuple<?, End>. I thought that combined with the large if else structures would help at least for the most basicly typed members of a Tuple.

  25. Alan Gutierrez Says:

    This project needs to be available from a Maven repository. I've built a pom.xml to build it for my own repository, but I'd love to see it at repo1.maven.org. Let me know if there is any way I can help.

  26. The Anti Spam Hub Says:

    [...] Adventures in Software » Blog Archive » Java Tuple [...]

  27. Morgon Says:

    It would be nice if there was a version that did not have the tuple classes required to implement Comparable! Simple enough to do on your own, but it would be nice to have in the library.

  28. alex Says:

    I also think, that It would be nice if there was a version that did not have the tuple classes required to implement Comparable

  29. qedisk Says:

    Yes I agree. Version without necessity of using comparable!

  30. MC Murphy Says:

    The netbeans 6.7 IDE compiler doesn't seem to like:

    public <T extends Comparable> Tuple<T, Tuple> prepend(T m) {
    return new Tuple<T, Tuple>(m, this);
    }

    inside the Tuple class. The tuple class is defined as:

    public class Tuple<First extends Comparable, Rest extends Comparable> implements SeparatedAppender, Comparable<Tuple> {...}

    The compiler error is:

    "type parameter com.mallardsoft.tuple.Tuple is not within its bound"

    Now I can't see why it shouldn't accept this. I wonder whether this is a bug in the netbeans 6.7 IDE compiler or whether its
    because the Tuple class has not been fully defined yet (i.e. this is within the class definition)?

    I've looked online and not found any articles on compiler bugs for netbeans 6.7 IDE yet. I'll have to try a different compiler as well.

  31. Jason Frank Says:

    Here's another vote for not requiring Comparable. I want to use this for the "multi-valued return" feature. I want to return a Pair with a String and a List inside it. I can't do it because List does not implement Comparable. Since I'm not going to compare them, that is not an issue for me, but it means that I can't use this library.

  32. Rainer Schnitker Says:

    The tuple classes should implement Serializable. Required for remoting.

  33. Jacek Says:

    Can you add your library to a Maven repo? It would help it's spread greatly....

  34. Norman Shelley Says:

    Any feedback on the problem mentioned in July 24, 2009?

    I too am having this problem
    Product Version: NetBeans IDE 6.7.1 (Build 200907230233)
    Java: 1.6.0_16; Java HotSpot(TM) Client VM 14.2-b01
    System: Windows XP version 5.1 running on x86; Cp1252; en_US (nb)
    Userdir: C:\Documents and Settings\shellnk1\.netbeans\6.7

    MC Murphy Says:

    July 24th, 2009 at 8:08 am
    The netbeans 6.7 IDE compiler doesn't seem to like:

    public Tuple prepend(T m) {
    return new Tuple(m, this);
    }

    inside the Tuple class. The tuple class is defined as:

    public class Tuple implements SeparatedAppender, Comparable {...}

    The compiler error is:

    "type parameter com.mallardsoft.tuple.Tuple is not within its bound"

  35. Casey Says:

    And yet another vote for not requiring Comparable. Similar to Jason Frank I want to have Tuples with Collections inside them (Lists, Maps, etc). Any chance the library will get that update?

  36. pangea Says:

    great work...can i copy the code and change the package names...leaving the confidential info as is? problem is that i cant have too many jars in my webapp ...so want to bundle these with others...1 more suggestion....why dont u donate (or whatever is more appropriate) this to google-guvava project...i think this is a perfect addition there...tx again

  37. Blu ray software Says:

    Thx for sharing!

  38. Christian W. Says:

    I used the tuple-class in NetBeans 6.5 without any problems. Since NB 6.8 I get the
    error: "type parameter * is not within its bound" as mentioned twice before.

    As Jason Frank says, one can delete all comparation-possibilities. I substituted:
    1.
    "public class Tuple<First extends Comparable, Rest extends Comparable> implements SeparatedAppender, Comparable<Tuple> {"
    by
    "public class Tuple implements SeparatedAppender {"

    2.
    "public <T extends Comparable> Tuple<T, Tuple> prepend(T m) {
    return new Tuple<T, Tuple>(m, this);
    }"
    by
    "public Tuple<T, Tuple> prepend(T m) {
    return new Tuple<T, Tuple>(m, this);
    }"
    and deleted
    3.
    /* public int compareTo(Tuple that) {
    int compare = this.first.compareTo(that.first);
    if (compare != 0)
    return compare;
    else
    return this.rest.compareTo(that.rest);
    }*/

    NB now compiles my project.

    But in order to stay compatible to all new NB versions and the original tuple-class, I need some hint how to get my project compiling without this ugly workaround. Isn't there any?

  39. Christoph Schulz Says:

    Hello,

    wrt. to the NetBeans compiler problem: What about specifying all arguments of the Tuple template explicitly (sorry for my C++ jargon), i.e.:

    public Tuple<T, Tuple > prepend(T m) {
    return new Tuple<T, Tuple >(m, this);
    }

    Does this work?

  40. Erich Herz Says:

    One more vote for not requiring the Tuple types to implement Comparable. In my opinion Tuple comparison should default to using object hashCode().

  41. victor Says:

    Hi, great library,

    But I found strange that the empty tuple does not exists. There is End but it is not a Tuple, so I can't use it where a Tuple is needed…

    Would be cool to have it (and maybe not really hard…)

  42. Aron Says:

    Hello, thanks for the library.
    I found it odd though, that there were no methods to update tuples, so I added them. I can email you Tuple.java if you wish. The methods are insert (opposite of extract), and setn (opposite of getn):

    /**
    * Change the first element in the tuple and return the rest.
    * To insert all elements from the tuple, chain insert calls.
    *
    * @param value
    * @return
    */
    public Rest insert(First value) {
    first = value;
    return rest;
    }

    public static <T1 extends Comparable, Rest extends Comparable> T1 set1(Tuple tuple, T1 value) {
    T1 result = Tuple.get1(tuple);
    tuple.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, Rest extends Comparable> T2 set2(Tuple<T1, Tuple> tuple, T2 value) {
    T2 result = Tuple.get2(tuple);
    tuple.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, Rest extends Comparable> T3 set3(Tuple<T1, Tuple<T2, Tuple>> tuple, T3 value) {
    T3 result = Tuple.get3(tuple);
    tuple.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, Rest extends Comparable> T4 set4(Tuple<T1, Tuple<T2, Tuple<T3, Tuple>>> tuple, T4 value) {
    T4 result = Tuple.get4(tuple);
    tuple.rest.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, Rest extends Comparable> T5 set5(Tuple<T1, Tuple<T2, Tuple<T3, Tuple<T4, Tuple>>>> tuple, T5 value) {
    T5 result = Tuple.get5(tuple);
    tuple.rest.rest.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable, Rest extends Comparable> T6 set6(Tuple<T1, Tuple<T2, Tuple<T3, Tuple<T4, Tuple<T5, Tuple>>>>> tuple, T6 value) {
    T6 result = Tuple.get6(tuple);
    tuple.rest.rest.rest.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable, T7 extends Comparable, Rest extends Comparable> T7 set7(Tuple<T1, Tuple<T2, Tuple<T3, Tuple<T4, Tuple<T5, Tuple<T6, Tuple>>>>>> tuple, T7 value) {
    T7 result = Tuple.get7(tuple);
    tuple.rest.rest.rest.rest.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable, T7 extends Comparable, T8 extends Comparable, Rest extends Comparable> T8 set8(Tuple<T1, Tuple<T2, Tuple<T3, Tuple<T4, Tuple<T5, Tuple<T6, Tuple<T7, Tuple>>>>>>> tuple, T8 value) {
    T8 result = Tuple.get8(tuple);
    tuple.rest.rest.rest.rest.rest.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable, T7 extends Comparable, T8 extends Comparable, T9 extends Comparable, Rest extends Comparable> T9 set9(Tuple<T1, Tuple<T2, Tuple<T3, Tuple<T4, Tuple<T5, Tuple<T6, Tuple<T7, Tuple<T8, Tuple>>>>>>>> tuple, T9 value) {
    T9 result = Tuple.get9(tuple);
    tuple.rest.rest.rest.rest.rest.rest.rest.rest.first = value;
    return result;
    }

    public static <T1 extends Comparable, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable, T7 extends Comparable, T8 extends Comparable, T9 extends Comparable, T10 extends Comparable, Rest extends Comparable> T10 set10(Tuple<T1, Tuple<T2, Tuple<T3, Tuple<T4, Tuple<T5, Tuple<T6, Tuple<T7, Tuple<T8, Tuple<T9, Tuple>>>>>>>>> tuple, T10 value) {
    T10 result = Tuple.get10(tuple);
    tuple.rest.rest.rest.rest.rest.rest.rest.rest.rest.first = value;
    return result;
    }

  43. Adventures in Software » Blog Archive » Java Tuple update Says:

    [...] findCharacter returns Pair<Boolean, Integer>. I published the source and got a few [...]

Leave a Reply

You must be logged in to post a comment.