Java Forum / First Aid / December 2007
when will Tuple be std?
apm35@student.open.ac.uk - 28 Dec 2007 13:22 GMT I am an experienced C++ programmer who has just recently started learning java. In C++ there is a type std::pair for an aggregate consisting of a first element and second element. There are moves to extend this in the next version of the std to provide a Tuple class as a general case where the aggregate can contain more than two members. I have the need for a Tuple in my java program and hoped it would be there as std. I cannot find it.
I have found the project, http://javatuple.com/index.shtml, which is useful and encouraging, but I wonder how long it will be before Tuple is std. The fact that this project exists shows I am not the only one that wants to see a Tuple class in java.
Regards,
Andrew Marlow
Lew - 28 Dec 2007 14:15 GMT > I have the need for a Tuple in my java program and hoped it would be > there as std. I cannot find it. A sexually-transmitted disease?
> I have found the project, http://javatuple.com/index.shtml, which is > useful and encouraging, but I wonder how long it will be before Tuple > is std. Never, but it only takes about ten minutes to write one.
public class Pair <T, U> { private final T first; private final U second; public Pair ( T t, U u ) { first = t; second = u; } public final T getFirst() { return first; } public final U getSecond() { return second; }
@SuppressWarnings ("unchecked" ) @Override public boolean equals( Object oth ) { if ( this == oth ) { return true; } if ( ! (oth instanceof Pair) ) { return false; } Pair <T, U> pair = (Pair<T, U>) oth; return (first == null? pair.first == null : first.equals( pair.first )) && (second == null? pair.second == null : second.equals( pair.second )); } @Override public int hashCode() { return first.hashCode() * 31 + second.hashCode(); } }
There you go, all your googling satisfied.
 Signature Lew
Eric Sosman - 28 Dec 2007 14:28 GMT > I am an experienced C++ programmer who has just recently started > learning java. In C++ there is a type std::pair for an aggregate [quoted text clipped - 8 lines] > is std. The fact that this project exists shows I am not the only one > that wants to see a Tuple class in java. If the elements of your Tuple have some important relationship to each other -- (x, f(x), f'(x), f''(x)), for example -- then they probably belong in a class that "understands" that relationship. If the elements are just J. Random Thingummies whose only connection is that one is first, another is second, and so on, then you may as well use `new Object[N]', Java's built-in all-purpose tuple.
If there's something else you're after, you'll need to explain more fully; I'm feeling particularly dense today.
 Signature Eric Sosman esosman@ieee-dot-org.invalid
Stefan Ram - 28 Dec 2007 17:54 GMT >If there's something else you're after, you'll need >to explain more fully; I'm feeling particularly dense >today. Sometimes, one wants to handle (e.g., compare) pairs in the sense, that two pairs are equal if both components are, and one does /not/ want to write a custom class each time but reuse a common tuple class, because one does not need more methods beyond those for comparison.
For example, my library
http://www.purl.org/stefan_ram/pub/ram-jar
has a »comparable tuple« class, so one can execute the following program.
public class Main {
/** A convenience method to construct a tuple. */ static de.dclj.ram.type.tuple.ComparableTuple <de.dclj.ram.type.tuple.DefaultComparableTuple> tuple( java.lang.Comparable ... args ) { return new de.dclj.ram.type.tuple.DefaultComparableTuple( args ); }
final static java.lang.String nl = java.lang.System.getProperty( "line.separator" ); public static void main( final java.lang.String[] args ) { java.lang.System.out.println ( tuple( 12000, "beta" ).hashCode() + nl + tuple( 12000, "beta" ).hashCode() + nl + tuple( 12001, "beta" ).hashCode() + nl + tuple( 12000, "betb" ).hashCode() + nl + tuple( 12000, "beta" ).equals( tuple( 12000, "beta" )) + nl + tuple( 12000, "beta" ).equals( tuple( 12001, "beta" )) + nl + tuple( 12000, "beta" ).equals( tuple( 12000, "betb" )) + nl );
final java.util.List<de.dclj.ram.type.tuple.ComparableTuple> list = new java.util.ArrayList<de.dclj.ram.type.tuple.ComparableTuple>(); list.add( tuple( 12000, "gamma" )); list.add( tuple( 10000, "alpha" )); list.add( tuple( 20000, "delta" )); list.add( tuple( 12000, "beta" )); java.util.Collections.sort( list ); java.lang.System.out.println( list ); }}
3029778 3029778 3029779 3029779 true false false
[( 10000; "alpha" ), ( 12000; "beta" ), ( 12000; "gamma" ), ( 20000; "delta" )]
With Java SE, a good approximation is to use an array and the static »hashCode« and »equals« methods from java.util.Arrays.
Stefan Ram - 28 Dec 2007 15:21 GMT >I have found the project, http://javatuple.com/index.shtml, which is >useful and encouraging, but I wonder how long it will be before Tuple >is std. The fact that this project exists shows I am not the only one >that wants to see a Tuple class in java. »Java was actually designed to have tuples from the start, but they never quite got in.« http://gbracha.blogspot.com/2007/02/tuples.html
Jan Burse - 28 Dec 2007 15:44 GMT Stefan Ram schrieb:
>> I have found the project, http://javatuple.com/index.shtml, which is >> useful and encouraging, but I wonder how long it will be before Tuple [quoted text clipped - 5 lines] > > http://gbracha.blogspot.com/2007/02/tuples.html "I totally agree with the need for tuples. The problem of "multiple return values" is indeed a pain."
Yes if you cultivate a functional programming style.
But you can adapt the beans programming style, which can be handy to return multiple values. So instead of heading a function (which works in Java only for m<=1):
Declaration:
public class Module public static return1 ... returnm fun(arg1,..,argn) { }
Use:
x1,..,xm = fun(a1,..,an)
You could do the following. Namely create an object for an invokation, and populate it before the invokation, and read the values after the invokation:
Declaration
public class Bean public void setArg1(arg1); ... public void setArgn(argn);
public return1 getReturn1(); ... public returnm getReturnm();
public void fun() { }
Use:
Bean bean=new Bean(); bean.setArg1(a1); ... bean.setArg1(a1); bean.fun(); x1 = bean.getReturn1(); ... xm = bean.getReturnm();
There are some pros and cons to the bean approach. Namely:
pros: Reentrant, as long as you follow the rule one thread per bean.
pros: Default values possible, you can recognize when a setter is not called.
pros: Optimizations possible when arguments are provided, for example some arguments can be provided before a looping call of fun, and some can be provided inside the loop.
cons: Less readable code, need to track very carefully when which argument is passed.
pros: Can even define familiy of releated functions, with related arguments and returns.
cons: Even less readable code, when multiple related functions are provided, and when side effects are not clear from the outside of the bean.
I first saw this "pattern" here:
Java Modeling in Color with UML, Coad, Lefebvre, De Luca, 1999
They use the color pink/the stereotype moment-interval for classes that are such functional beans. And they even aggregate such beans.
Best Regards
Stefan Ram - 28 Dec 2007 15:48 GMT >>http://gbracha.blogspot.com/2007/02/tuples.html >"I totally agree with the need for tuples. The >problem of "multiple return values" is indeed >a pain." »When I was helping Bill Joy and Guy L. Steele Jr. by reviewing drafts of the original Java Language Specification, I was originally upset that there was no way to do this. So I set out to find a small example program that obviously demanded such a feature, to convince them that multiple value returns must be added. I was unable to come up with one, and I could see that Java's philosphy was to leave out things that are rarely used and not crucial, so finally didn't say anything.«
http://dlweinreb.wordpress.com/2007/12/08/complaints-im-seeing-about-java/
Stefan Ram - 28 Dec 2007 16:52 GMT >But you can adapt the beans programming style, which >can be handy to return multiple values. So instead I have written several programs myself to show how multiple returns might be emulated in Java. Each approach has its advantages and disatvantages. I might add that, whenever I want to achieve something with Java, the lack of explicit multiple return values is not a problem for me.
So, here are my notes:
I assume a simple multiple-return task such as, in pseudocode:
operation "sumdiff" in x, y; out sum, difference; { sum = x + y; difference = x - y; }
Solution with public fields:
class Sumdiff { public Sumdiff( final int x, final int y ) { this.sum = x + y; this.difference = x - y; } public final int sum; public final int difference; }
public class Main { public static void main( final java.lang.String[] args ) { final Sumdiff result = new Sumdiff( 4, 2 ); java.lang.System.out.println ( result.sum + ", " + result.difference ); }}
6, 2
If you do not like public fields, you might use getters as well (which might be similar to you »beans« approach).
A »processor object« can created once and be used several times:
public class Main { public static void main( final java.lang.String[] args ) { final Processor processor = new Processor(); processor.set( 4, 2 ); processor.calculateSumDiff(); java.lang.System.out.println( processor.getSum() ); java.lang.System.out.println( processor.getDifference() ); processor.set( 8, 4 ); processor.calculateSumDiff(); java.lang.System.out.println( processor.getSum() ); java.lang.System.out.println( processor.getDifference() ); }}
class Processor { public void set( final int x, final int y ) { this.x = x; this.y = y; } public void calculateSumDiff() { this.sum = x + y; this.difference = x - y; } public java.lang.Integer getSum(){ return sum; } public java.lang.Integer getDifference(){ return difference; } int x; int y; int sum; int difference; }
To avoid allocation overhead of a result object, the client might provide and reuse such an object:
class Result { public int x; public int y; }
class Server { void run( final Result result, final int x, final int y ) { result.x = x + y; result.y = x - y; }}
public final class Main { private static Result result = new Result(); /* single allocation */ public static void main( final java.lang.String argv[] ) { Server server = new Server(); server.run( result, 1, 2 ); java.lang.System.out.println( result.x ); java.lang.System.out.println( result.y ); server.run( result, 3, 4 ); java.lang.System.out.println( result.x ); java.lang.System.out.println( result.y ); }}
One can also emulate multiple returns via multiple arguments, but only when adopting a »continuation passing style«. In the next example, the server »returns« a pair of random numbers to the client, by calling back a method provided by the client.
interface Client { void continuation( int x, int y ); }
class Server { static java.util.Random rand = new java.util.Random(); static void getPair( final Client client ) { client.continuation( rand.nextInt( 11 ), rand.nextInt( 21 )); }}
class Example implements Client { public void continuation( final int x, final int y ) { java.lang.System.out.println( x + ", " + y ); } public void main() { Server.getPair( this ); }}
public class Main { public static void main( final java.lang.String[] args ) { new Example().main(); }}
But, as said, I rarely ever (actually: never) have needed any of these multiple return value emulations in my own projects.
Possibly this is because I already have accounted for the properties and limitations of Java when I was designing my classes. So I have designed them from the start in such a way that multiple return values are not needed.
Mark Space - 28 Dec 2007 16:54 GMT > I am an experienced C++ programmer who has just recently started > learning java. In C++ there is a type std::pair for an aggregate > consisting of a first element and second element. There are moves to The problem with tuple is, in my opinion, that once you have tuple, why not a triple or a quadruple? Those are just as often used. And once you start thinking along these lines, it becomes obvious (again imo) that arrays or ArrayList or other Collection is easier and already present.
Plus as Lew pointed out making a new type of object is almost trivial. I've made a special purpose triple but never a tuple, so tuple wouldn't help me. If it's truly quick and dirty I skip the nice getters and setters and just make the instance variables public.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|