views:

1143

answers:

5

I want to pass 2 arrays to a function in Java and have them sorted in the calling function. How do i use a function to accomplish that?

I could have the function return an object with 2 arrays, but is there a non object-oriented solution to this?

EDIT : I this particular situation I cant use the inbuilt Array.sort function in Java. Lets say the 2 arrays are height and weight. They are of the same length, and the same index correspond to the same person's height and weight on both arrays. I want to sort the height array in ascending order, while sorting the weight array corresponding to the height array. So using the sort function would mess up the relations between the 2 arrays.

+4  A: 
public void sort2(Object o1[], Object o2[])
{
  Arrays.sort(o1);
  Arrays.sort(o2);
}

Slightly more sophisticated:

public <T> void sort2(T o1[], T o2[],  Comparator<? super T> c)
{
  Arrays.sort(o1, c);
  Arrays.sort(o2, c);
}

EDIT: Generally, when you use parallel arrays, that means you are not using objects properly. To follow your example, you should have a Comparable Person class with height and weight properties. Of course, like Mehrdad said, you can manually implement a parallel array sorting algorithm, but it's really not ideal.

Matthew Flaschen
+4  A: 

When you pass an array to a function, it's not copied. Just the reference of it is copied and passed to the function which will point to the same location. You just need to sort the arrays in-place.

EDIT: To solve the actual sorting problem, you can use any sorting algorithm to sort height array. The only difference is that when you're swapping two elements in height sorting process, you should also swap the corresponding elements in weight array.

Mehrdad Afshari
A: 

So you want function A to call function B. Then B sort the arrays and A get back the two sorted array ?

Since parameters are reference in Java, if you modify your objects in B, A will see the modified versions.

In C# it can even be said explicitly with the out keyword, that tells everyone that the function will modify the out parameter.

Ksempac
This is wrong. out would mean the the caller's object[] variable would point to a new object[]. That is not what's happening here.
Matthew Flaschen
+1  A: 

While using two separate arrays and keeping their sort in sync is possible, using this type of solution may lead to bugs that are hard to find later on. For example, if the syncs between the arrays don't work correctly, then the wrong weights may be matched with the heights.

One way to avoid this type of problem is to encapsulate the height/weight in a class so they will always be in sync. In Figure 1 there is a class named Person that has height, weight, and name as attributes. If you are always going to sort by height ascending, then you can implement the compareTo() method as shown in Figure 1.

Figure 2 shows a junit test case to demonstrate how to sort a list of Persons. The test case also demonstrates how to sort by weight. In both cases there is never a sync issue between weight and height since the sort is on the object that encapsulates them.

Figure 1 - Person class



public class Person implements Comparable {
    private Float height;
    private Float weight;
    private String name;

    public Person(){}

    public Person(Float height, Float weight, String name) {
     this.height = height;
     this.weight = weight;
     this.name = name;
    }

    public Float getHeight() {
     return height;
    }
    public void setHeight(Float height) {
     this.height = height;
    }
    public Float getWeight() {
     return weight;
    }
    public void setWeight(Float weight) {
     this.weight = weight;
    }

    public String getName() {
     return name;
    }
    public void setName(String name) {
     this.name = name;
    }

    public int compareTo(Person other) {
     //sort by height ascending
     return this.height.compareTo(other.getHeight());
    }
}

Figure 2 - junit test class



import junit.framework.TestCase;
import java.util.*;

public class PersonTest extends TestCase {

    private List personList = new ArrayList();

    public PersonTest(String name) {
     super(name);
    }

    public void testCompareTo() {
     personList.add(new Person(72F,125F,"Bob"));// expect 3rd when sorted by height asc
     personList.add(new Person(69.9F,195F,"Jack"));// expect 2nd when sorted by height asc
     personList.add(new Person(80.05F,225.2F,"Joe"));// expect 4th when sorted by height asc
     personList.add(new Person(57.02F,89.9F,"Sally"));// expect 1st when sorted by height asc
     Collections.sort(personList);
     assertEquals("Sally should be first (sorted by height asc)",personList.get(0).getName(),"Sally");
     assertEquals("Jack should be second (sorted by height asc)",personList.get(1).getName(),"Jack");
     assertEquals("Bob should be third (sorted by height asc)",personList.get(2).getName(),"Bob");
     assertEquals("Joe should be fourth (sorted by height asc)",personList.get(3).getName(),"Joe");

     Collections.sort(personList,new Comparator() {
      public int compare(Person p1, Person p2) {
       //sort by weight ascending
       return p1.getWeight().compareTo(p2.getWeight());
      }
     });
     assertEquals("Sally should be first (sorted by weight asc)",personList.get(0).getName(),"Sally");
     assertEquals("Bob should be second (sorted by weight asc)",personList.get(1).getName(),"Bob");
     assertEquals("Jack should be third (sorted by weight asc)",personList.get(2).getName(),"Jack");
     assertEquals("Joe should be fourth (sorted by weight asc)",personList.get(3).getName(),"Joe");  
    }

}

rich
A: 

You can return an array of arrays or an object which contains two arrays. However, it sounds like the values in the two arrays should be correlated so you should really have one array of objects which contains the two values.

BTW: I wouldn't use Float ever and float I would avoid as well (as it only accurate to 6 places) I would suggest using int, long or double.

Peter Lawrey