Need to return multiple values.

Discussion in 'Java' started by Nafai, Feb 17, 2005.

  1. Nafai

    Nafai Guest

    Hello. I have a method like this:


    public void p(Integer a, Integer b, Integer c)
    {
    ....
    }

    b and c should be output data and a input.

    But I don't know how to assing a value to b and c inside p without
    changin the objet where they point.

    That is:

    public void p(X a, Integer b, Integer c)
    {
    ...
    b = doSomeThing(a);
    c = doSomeThing2(a);
    }

    That doesn't make b and c to point to the result of doSomeThing(a) when
    p ends.

    What can I do?

    Thank-you.
     
    Nafai, Feb 17, 2005
    #1
    1. Advertising

  2. In article <8A4Rd.452864$>,
    Nafai <> wrote:
    >Hello. I have a method like this:
    >
    >
    >public void p(Integer a, Integer b, Integer c)
    >{
    >...
    >}
    >
    >b and c should be output data and a input.
    >
    >But I don't know how to assing a value to b and c inside p without
    >changin the objet where they point.
    >
    >That is:
    >
    >public void p(X a, Integer b, Integer c)
    >{
    > ...
    > b = doSomeThing(a);
    > c = doSomeThing2(a);
    >}
    >
    >That doesn't make b and c to point to the result of doSomeThing(a) when
    >p ends.


    1) Return an object containing b and c (don't pass them as parameters, or
    2) Pass a parameter with b and c members, which get assigned in p, or
    3) Let callers of p call doSomeThing and doSomething2 directly, e.g.
    x = Quotient(m,n) // quotient of m/n
    y = Remainder(m,n) // remainder of m/n
    --
    "Yo' ideas need to be thinked befo' they are say'd" - Ian Lamb, age 3.5
    http://www.cs.queensu.ca/~dalamb/ qucis->cs to reply (it's a long story...)
     
    David Alex Lamb, Feb 17, 2005
    #2
    1. Advertising

  3. Nafai

    Eric Sosman Guest

    Nafai wrote:
    > Hello. I have a method like this:
    >
    >
    > public void p(Integer a, Integer b, Integer c)
    > {
    > ...
    > }
    >
    > b and c should be output data and a input.
    >
    > But I don't know how to assing a value to b and c inside p without
    > changin the objet where they point.
    >
    > That is:
    >
    > public void p(X a, Integer b, Integer c)
    > {
    > ...
    > b = doSomeThing(a);
    > c = doSomeThing2(a);
    > }
    >
    > That doesn't make b and c to point to the result of doSomeThing(a) when
    > p ends.
    >
    > What can I do?


    There are many solutions, with different advantages
    and drawbacks. One of the simplest is

    public Integer[] p(X a) {
    Integer[] result = new Integer[2];
    ...
    result[0] = doSomeThing(a);
    result[1] = doSomething2(a);
    ...
    return result;
    }

    --
     
    Eric Sosman, Feb 17, 2005
    #3
  4. Nafai

    Alex Guest

    Integer is immutable (like String, for example).
    So, use mutable objects if you _really_ need to change them in this
    way.
    Which is definitely not recommended as good OP.

    int i[]=new int[5];
    i[2]=2;
    call(i);
    .....
    public void call(int a[]) {
    a[2]=22;
    }

    Alex Kizub.
     
    Alex, Feb 17, 2005
    #4
  5. Nafai <> scribbled the following
    on comp.lang.java.programmer:
    > Hello. I have a method like this:



    > public void p(Integer a, Integer b, Integer c)
    > {
    > ...
    > }


    > b and c should be output data and a input.


    > But I don't know how to assing a value to b and c inside p without
    > changin the objet where they point.


    > That is:


    > public void p(X a, Integer b, Integer c)
    > {
    > ...
    > b = doSomeThing(a);
    > c = doSomeThing2(a);
    > }


    > That doesn't make b and c to point to the result of doSomeThing(a) when
    > p ends.


    > What can I do?


    > Thank-you.


    Others have already answered your question. I only want to add that I
    have theorised about adding aggregate types, found in functional
    languages, to languages such as C or Java. In this example, it would
    work like this:

    public (Integer, Integer) p(X a)
    {
    return (doSomething(a), doSomething2(a));
    }

    and then called like this:

    (b, c) = p(a);

    The only problem is that if "b" and "c" are the same variable then the
    behaviour is undefined. I have not found a solution to this, and seeing
    as the entire problem is theoretical at best, I have not bothered to
    try.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "'I' is the most beautiful word in the world."
    - John Nordberg
     
    Joona I Palaste, Feb 17, 2005
    #5
  6. Joona I Palaste
    > public (Integer, Integer) p(X a)
    > {
    > return (doSomething(a), doSomething2(a));
    > }
    >
    > and then called like this:
    >
    > (b, c) = p(a);
    >
    > The only problem is that if "b" and "c" are the same variable then the
    > behaviour is undefined. I have not found a solution to this, and seeing
    > as the entire problem is theoretical at best, I have not bothered to
    > try.


    Simply solution is, the compiler have to complain about the ambigous variable using.

    Heiner Kuecker
    Internet: http://www.heinerkuecker.de http://www.heiner-kuecker.de
    JSP WorkFlow PageFlow Page Flow FlowControl Navigation: http://www.control-and-command.de
    Java Expression Formula Parser: http://www.heinerkuecker.de/Expression.html
    Domain Specific Languages http://www.heinerkuecker.de/DomainParser.html
     
    Heiner Kücker, Feb 17, 2005
    #6
  7. Nafai

    Yamin Guest

    Hey Nafai,

    As others have mentioned, Integer is immutable for its own reasons.
    I've often wondered why they didn't have an easy to use IntegerBuffer,
    like they have StringBuffer. They have intBuffer, but its not quite
    what you'd want.

    So these are the basic options:
    1. create a custom structure just for the function (I don't like doing
    this)
    2. Pass an array of objects
    3. Use a Map
    4. Define your own mutable Integer class.

    I like to use 3 in cases where performance is not an issue. It helps
    keep the function definition simple.

    Use strings as keys...just use the parameter names.
    //pass the parameters into the function
    HashMap abc;
    abc.put("a", a);
    abc.put("b", b);
    abc.put("c", c);

    //Extract them
    public void p(HashMap abc)
    {
    Integer a = HashMap.get("a");
    Integer b = HashMap.get("b");
    Integer c = HashMap.get("c");
    }


    This beats an array IMO because ur not dealing with indices which you
    could screw up if you change the number of parameters of whatever...

    Yamin

    Nafai wrote:
    > Hello. I have a method like this:
    >
    >
    > public void p(Integer a, Integer b, Integer c)
    > {
    > ...
    > }
    >
    > b and c should be output data and a input.
    >
    > But I don't know how to assing a value to b and c inside p without
    > changin the objet where they point.
    >
    > That is:
    >
    > public void p(X a, Integer b, Integer c)
    > {
    > ...
    > b = doSomeThing(a);
    > c = doSomeThing2(a);
    > }
    >
    > That doesn't make b and c to point to the result of doSomeThing(a)

    when
    > p ends.
    >
    > What can I do?
    >
    > Thank-you.
     
    Yamin, Feb 17, 2005
    #7
  8. "Heiner Kücker" <> scribbled the following
    on comp.lang.java.programmer:
    > Joona I Palaste
    >> public (Integer, Integer) p(X a)
    >> {
    >> return (doSomething(a), doSomething2(a));
    >> }
    >>
    >> and then called like this:
    >>
    >> (b, c) = p(a);
    >>
    >> The only problem is that if "b" and "c" are the same variable then the
    >> behaviour is undefined. I have not found a solution to this, and seeing
    >> as the entire problem is theoretical at best, I have not bothered to
    >> try.


    > Simply solution is, the compiler have to complain about the ambigous variable using.


    And what if they are array members whose indices are calculated at
    run-time?

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "C++ looks like line noise."
    - Fred L. Baube III
     
    Joona I Palaste, Feb 18, 2005
    #8
  9. Yamin
    > Hey Nafai,
    >
    > As others have mentioned, Integer is immutable for its own reasons.
    > I've often wondered why they didn't have an easy to use IntegerBuffer,
    > like they have StringBuffer. They have intBuffer, but its not quite
    > what you'd want.
    >
    > So these are the basic options:
    > 1. create a custom structure just for the function (I don't like doing
    > this)
    > 2. Pass an array of objects
    > 3. Use a Map
    > 4. Define your own mutable Integer class.
    >
    > I like to use 3 in cases where performance is not an issue. It helps
    > keep the function definition simple.
    >
    > Use strings as keys...just use the parameter names.
    > //pass the parameters into the function
    > HashMap abc;
    > abc.put("a", a);
    > abc.put("b", b);
    > abc.put("c", c);
    >
    > //Extract them
    > public void p(HashMap abc)
    > {
    > Integer a = HashMap.get("a");
    > Integer b = HashMap.get("b");
    > Integer c = HashMap.get("c");
    > }
    >
    >
    > This beats an array IMO because ur not dealing with indices which you
    > could screw up if you change the number of parameters of whatever...


    What yout meant are named parameters.
    A good thing if the compiler supported this.

    --
    Heiner Kuecker
    Internet: http://www.heinerkuecker.de http://www.heiner-kuecker.de
    JSP WorkFlow PageFlow Page Flow FlowControl Navigation: http://www.control-and-command.de
    Java Expression Formula Parser: http://www.heinerkuecker.de/Expression.html
    Domain Specific Languages http://www.heinerkuecker.de/DomainParser.html
     
    Heiner Kücker, Feb 18, 2005
    #9
  10. Nafai

    dbr Guest

    > What yout meant are named parameters.
    > A good thing if the compiler supported this.


    You might want to check the Nice language, which is an extension of
    Java that does support named parameters. It also supports tuples, which
    allows methods to return multiple values.

    http://nice.sf.net

    As to what
    (x,x) = (1,2);
    should do, I think it makes to follow, as usual, the left-to-right
    evaluation order. So first x is assigned 1, then x is assigned 2.

    Daniel Bonniot
     
    dbr, Feb 18, 2005
    #10
  11. Nafai

    Guest

    dbr wrote:
    > > What yout meant are named parameters.
    > > A good thing if the compiler supported this.

    >
    > You might want to check the Nice language, which is an extension of
    > Java that does support named parameters. It also supports tuples,

    which
    > allows methods to return multiple values.
    >
    > http://nice.sf.net
    >
    > As to what
    > (x,x) = (1,2);
    > should do, I think it makes to follow, as usual, the left-to-right
    > evaluation order. So first x is assigned 1, then x is assigned 2.
    >
    > Daniel Bonniot


    Python has this exact syntax:

    a, b = 1, 2

    It's pretty easy to do in C++ too:

    pair<int,int> MyFunction(int a) {
    ...
    return pair<int,int>(b, c);
    }
     
    , Feb 19, 2005
    #11
  12. scribbled the following
    on comp.lang.java.programmer:
    > dbr wrote:
    >> > What yout meant are named parameters.
    >> > A good thing if the compiler supported this.

    >>
    >> You might want to check the Nice language, which is an extension of
    >> Java that does support named parameters. It also supports tuples,

    > which
    >> allows methods to return multiple values.
    >>
    >> http://nice.sf.net
    >>
    >> As to what
    >> (x,x) = (1,2);
    >> should do, I think it makes to follow, as usual, the left-to-right
    >> evaluation order. So first x is assigned 1, then x is assigned 2.
    >>
    >> Daniel Bonniot


    > Python has this exact syntax:


    > a, b = 1, 2


    > It's pretty easy to do in C++ too:


    > pair<int,int> MyFunction(int a) {
    > ...
    > return pair<int,int>(b, c);
    > }


    Yes, but how do you assign the values from your pair<int, int> to two
    int variables such as a and b? I don't know C++ very well, so I don't
    know how, or if, it can be done.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "To know me IS to love me."
    - JIPsoft
     
    Joona I Palaste, Feb 19, 2005
    #12
  13. Nafai

    Ryan Stewart Guest

    "Joona I Palaste" <> wrote in message
    news:cv2ta4$rgi$...
    [...]
    > public (Integer, Integer) p(X a)
    > {
    > return (doSomething(a), doSomething2(a));
    > }
    >
    > and then called like this:
    >
    > (b, c) = p(a);
    >
    > The only problem is that if "b" and "c" are the same variable then the
    > behaviour is undefined. I have not found a solution to this, and seeing
    > as the entire problem is theoretical at best, I have not bothered to
    > try.
    >

    I'd say you would define the expression to be the same as:
    b = p(a)[first return value];
    c = p(a)[second return value];

    Therefore if both b and c are the same somehow, they would both end up having
    the second return value.
     
    Ryan Stewart, Feb 19, 2005
    #13
  14. Ryan Stewart <> scribbled the following
    on comp.lang.java.programmer:
    > "Joona I Palaste" <> wrote in message
    > news:cv2ta4$rgi$...
    > [...]
    >> public (Integer, Integer) p(X a)
    >> {
    >> return (doSomething(a), doSomething2(a));
    >> }
    >>
    >> and then called like this:
    >>
    >> (b, c) = p(a);
    >>
    >> The only problem is that if "b" and "c" are the same variable then the
    >> behaviour is undefined. I have not found a solution to this, and seeing
    >> as the entire problem is theoretical at best, I have not bothered to
    >> try.
    >>

    > I'd say you would define the expression to be the same as:
    > b = p(a)[first return value];
    > c = p(a)[second return value];


    > Therefore if both b and c are the same somehow, they would both end up having
    > the second return value.


    Good, thanks. Now should I write a JSR about this? Or has someone
    already written one?

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "And according to Occam's Toothbrush, we only need to optimise the most frequent
    instructions."
    - Teemu Kerola
     
    Joona I Palaste, Feb 19, 2005
    #14
  15. Nafai

    xarax Guest

    "Joona I Palaste" <> wrote in message
    news:cv88ht$mh1$...
    > Ryan Stewart <> scribbled the following
    > on comp.lang.java.programmer:
    >> "Joona I Palaste" <> wrote in message
    >> news:cv2ta4$rgi$...
    >> [...]
    >>> public (Integer, Integer) p(X a)
    >>> {
    >>> return (doSomething(a), doSomething2(a));
    >>> }
    >>>
    >>> and then called like this:
    >>>
    >>> (b, c) = p(a);
    >>>
    >>> The only problem is that if "b" and "c" are the same variable then the
    >>> behaviour is undefined. I have not found a solution to this, and seeing
    >>> as the entire problem is theoretical at best, I have not bothered to
    >>> try.
    >>>

    >> I'd say you would define the expression to be the same as:
    >> b = p(a)[first return value];
    >> c = p(a)[second return value];

    >
    >> Therefore if both b and c are the same somehow, they would both end up having
    >> the second return value.

    >
    > Good, thanks. Now should I write a JSR about this? Or has someone
    > already written one?


    It will likely be rejected. The traditional ways of returning
    multiple values are:

    1. Pass a reference to output container object as input parameter.

    2. Return an array.

    3. Return a container object.

    These techniques are so easy to use and understand, that
    I doubt that changing the language to accommodate your
    suggestion will happen.
     
    xarax, Feb 19, 2005
    #15
  16. On Thu, 17 Feb 2005 17:33:56 +0000, Nafai wrote:

    > Hello. I have a method like this:
    >
    >
    > public void p(Integer a, Integer b, Integer c)
    > {
    > ...
    > }
    >
    > b and c should be output data and a input.
    >
    > But I don't know how to assing a value to b and c inside p without
    > changin the objet where they point.
    >
    > That is:
    >
    > public void p(X a, Integer b, Integer c)
    > {
    > ...
    > b = doSomeThing(a);
    > c = doSomeThing2(a);
    > }
    >
    > That doesn't make b and c to point to the result of doSomeThing(a) when
    > p ends.
    >
    > What can I do?


    Why not use some Pair class?

    import java.io.Serializable;

    /**
    * convenience class for pairs of values. This class provides basic type
    * safety, and can be used as a {@link java.util.Map}-key, and similar.
    *
    * Note that Serialization can only occur successfully if the type parameters T1
    * and T2 also implement the {@link java.io.Serializable} interface.
    *
    */
    public class Pair<T1, T2> implements Serializable, Cloneable {

    private static final long serialVersionUID = 3690473610825577009L;

    private final T1 first;
    private final T2 second;

    /**
    * creates a new Pair of values.
    * @param first first value
    * @param second second value
    */

    public Pair(T1 first, T2 second) {
    this.first = first;
    this.second = second;
    }

    /**
    * retrieves the first value of pair.
    *
    * @return the first value
    */

    public T1 getFirst() {
    return first;
    }

    /**
    * retrieves the second value of pair.
    *
    * @return the second value
    */
    public T2 getSecond() {
    return second;
    }

    /**
    * computes the hashcode for this object. This implementation is
    * consistent with equals, if the member objects have hashcodes that
    * are consistent with equals. It handles null-values gracefully.
    *
    * @return the hashcode
    */
    @Override
    public int hashCode(){
    int firstCode = first != null ? first.hashCode() : 0;
    int secondCode = second != null ? second.hashCode() >> 1 : 0;
    return firstCode ^ secondCode;
    }

    /**
    * compares two objects of class Pair for equality. A pair is equal if
    * it's members either fulfill reference equality (==) or if their
    * equals(Object) methods both return true.
    *
    * @param o another object
    * @return true if the pairs are equal
    */
    @Override
    public boolean equals(Object o){
    if (o == this)
    return true;

    if (o == null)
    return false;

    if (o instanceof Pair){
    Pair<?,?> that = (Pair<?,?>) o;
    Object thatFirst = that.getFirst();
    Object thatSecond = that.getSecond();

    if (thatFirst != first){
    if (first == null || !first.equals(thatFirst))
    return false;
    }

    if (thatSecond != second){
    if (second == null || !second.equals(thatSecond))
    return false;
    }

    return true;
    }

    return false;
    }

    /**
    * returns a shallow copy of this Pair. The copy may be quicker
    * then the obvious new Pair<T1, T2>(this.getFirst(), this.getSecond())
    * method of copying.
    *
    * @return a copy of this object.
    */

    @Override
    @SuppressWarnings("unchecked")
    public Pair<T1, T2> clone(){
    try {
    return (Pair<T1, T2>) super.clone();
    } catch (CloneNotSupportedException e) {
    throw new AssertionError(e);
    }
    }
    }

    --
    In pioneer days they used oxen for heavy pulling, and when one ox
    couldn't budge a log, they didn't try to grow a larger ox. We shouldn't
    be trying for bigger computers, but for more systems of computers.
    --- Rear Admiral Grace Murray Hopper
     
    Stefan Schulz, Feb 20, 2005
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. smen
    Replies:
    3
    Views:
    11,391
    Scott Allen
    Jan 9, 2004
  2. Jay Dorsey

    return multiple values from fuction

    Jay Dorsey, Nov 6, 2003, in forum: Python
    Replies:
    6
    Views:
    400
  3. Robert Brewer
    Replies:
    2
    Views:
    243
    John Roth
    Nov 17, 2004
  4. Greenhorn
    Replies:
    15
    Views:
    884
    Keith Thompson
    Mar 6, 2005
  5. Chris Rebert
    Replies:
    1
    Views:
    725
    Bobby
    May 28, 2009
Loading...

Share This Page