tags:

views:

213

answers:

10

Hi,

I have a long piece of code that calculates two values (doubles) for me, I use this piece of code in a few places - to stick with DRY principles I should refactor this bit of code to a nice unit testable method. However I cant make it return two doubles, and doubles are primitive so cannot be passed by value and manipulated. The cleanest way I can think of doing this is by making this method return an double[]. Can anyone think of a better way?

Thanks

+3  A: 

A class (immutable) with two double fields? Might even want to add some interesting methods to the class.

The other way around is to have the method take a callback object.

Tom Hawtin - tackline
+3  A: 
double[] arr = {val1, val2};
return arr

or go with a Pair-like class that encapsulates 2 values...

jspcal
+2  A: 

If the two doubles can be thought of as a logical pairing of values, then it might make sense to bundle them in a simple object?

Rob
+2  A: 

I'm more of a C++ guy, but creating an object of your own called Pair which can hold 2 doubles and can be passed by reference makes sense to me.

RC
+9  A: 

Firstly, all variables are passed by value in Java, not just primitives. It's just that objects can be mutable. It's important to understand that. For example:

public void addHour(Date date) {
  date.setTime(date.getTime() + 3600 * 1000);
}

The date is passed by value but Date is mutable so it can be modified but try and do this:

public void addHour(Date date) {
  date = new Date(date.getTime() + 3600 * 1000);
}

and it won't change the date. Why? Because date is a reference but is passed by value.

Secondly, do these doubles relate to each other in some way? If so wrap them in a class than describes this relationship like:

public class Coordinate {
  private final double x;
  private final double y;

  public Coordinate(double x, double y) {
    this.x = x;
    this.y = y;
  }

  public double getX() { return x; }
  public double getY() { return y; }
}
cletus
No no no no no! All variables are passed by value in Java. Primitives are passed by value and pointers to objects are passed by value. Nothing is _ever_ truly passed by reference. This is proven by the fact that you can't write a swap method in Java without `return`ing both values...
Chinmay Kanchi
Did you mean "value", rather than "reference", in that first sentence?
Rob
@Rob: yes I did mean "pass by value". Typo fixed, thanks.
cletus
Heh, posted my comment while you were editing... sorry about that.
Chinmay Kanchi
@Chinmay ... unless you put both values into an double[2] and pass the array ;)
Andreas_D
@Chinmay: no problem. :)
cletus
@Andreas: the array is still passed by value. Like `Date` an array is just a mutable object so the *elements* can be modified by the *array* itself cannot.
cletus
@Andreas: True... but that doesn't count, since you're modifying the _contents_ of the array, not the array itself. I'm getting a bit sick of "in Java, objects are passed by reference" though when it's patently not true.
Chinmay Kanchi
Quick thought, in this sense what's the behavior of `Double`, `Integer` wrapper classes? Also would it be smart to create some sort of `ReferentialDouble` or something or is that just reinventing the wheel?
Esko
You could use an AtomicReference http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/AtomicReference.html. I wouldn't bother though.
cletus
@cletus: That would autobox the actual value though, lets assume that for some odd reason I'd like to avoid the Object wrapper entirely.
Esko
+1  A: 

A double array is the most obvious answer. You can make it a bit safer by having a wrapper object like this:

  public class MyTwoDoubles {

       public MyTwoDoubles(double one, double two) { ... }

       public double getOne() { ... }

       public double getTwo() { ... }
  }
Yishai
+4  A: 

You could encapsulate them in a class for this purpose.

You could also give a double[] parameter to the method that calculates them and where it will put the calculated values in. This can be rather efficent as the caller code can reuse this array for successive invocations if performance is important.

x4u
"This can be rather efficent as the caller code can reuse this array for successive invocations if performance is important." This is premature optimization if I ever saw one, plus with a modern GC it's hard to say what is performant... so beware.
sleske
+2  A: 

Create an new class that has two double properties with getters and setters and constructor if you like (and equals and hashcode...) and make the method return that type of object. A generic way to do that would be a Pair class. This is a common pattern and you should find code snippets everywhere (e.g. in the netbeans code base).

Manfred Moser
+2  A: 

You have several options:

  1. Return an array
  2. Return a List<double>
  3. Return an object of a class that wraps your two doubles

And by the way, Java does not pass objects by reference. It passes pointers to objects by value. http://javadude.com/articles/passbyvalue.htm

Chinmay Kanchi
A: 

You can rather use Wrapper classes which are of reference types For every value type you can find a wrapper class. for your case java.lang.Double can be used,hope this solves the purpose But still as a good design i suggest you not to alter the object value inside the method. Instead refactor the code in such a way you call it twice and return two different values then assign it to the original. As a good practice its not advisible to alter object value inside a method

Ravisha