在Java中对数组进行排序

3
我希望在Java中将2个数组传递给一个函数,并在调用函数时对它们进行排序。如何使用函数来实现?
我可以让函数返回一个具有2个数组的对象,但是是否有非面向对象的解决方案?
编辑:在这种特定情况下,我不能使用Java中内置的Array.sort函数。假设这2个数组是身高和体重。它们长度相同,相同索引对应于两个数组中同一人的身高和体重。我想按升序对身高数组进行排序,同时对应于身高数组排序体重数组。因此,使用sort函数会破坏2个数组之间的关系。
5个回答

5
public void sort2(Object o1[], Object o2[])
{
  Arrays.sort(o1);
  Arrays.sort(o2);
}

稍微更加复杂:
public <T> void sort2(T o1[], T o2[],  Comparator<? super T> c)
{
  Arrays.sort(o1, c);
  Arrays.sort(o2, c);
}

编辑:通常,当你使用平行数组时,这意味着你没有正确使用对象。按照你的例子,你应该有一个具有身高和体重属性的可比较的 Person 类。当然,就像 Mehrdad 所说的那样,你可以手动实现平行数组排序算法,但这真的不是理想的方法。


4
当你将数组传递给函数时,它并不会被复制。只有它的引用被复制并传递给函数,该引用将指向相同的位置。你只需要原地对数组进行排序。
编辑:为了解决实际的排序问题,你可以使用任何排序算法来对“height”数组进行排序。唯一的区别是,在“height”排序过程中交换两个元素时,你还应该交换“weight”数组中相应的元素。

1

虽然使用两个单独的数组并保持它们的排序同步是可能的,但使用这种类型的解决方案可能会导致难以在以后找到的错误。例如,如果数组之间的同步不正确,则可能会将错误的重量与身高匹配。

避免这种类型的问题的一种方法是封装身高/体重在一个类中,以便它们始终保持同步。在图1中,有一个名为Person的类,它具有身高、体重和姓名作为属性。如果您总是按身高升序排序,则可以实现如图1所示的compareTo()方法。

图2显示了一个junit测试用例,演示如何对Person列表进行排序。测试用例还演示了如何按体重排序。在两种情况下,由于排序是在封装它们的对象上进行的,因此重量和身高之间永远不会出现同步问题。

图1 - Person



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());
    }
}

图2 - JUnit测试类



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");      
    }

}


0

所以你想让函数A调用函数B,然后由B对数组进行排序,A再获取这两个已排序的数组是吗?

在Java中,由于参数是引用类型,如果你在B中修改了对象,A将会看到修改后的版本。

而在C#中,可以使用out关键字明确表示该函数将修改out参数的值。


这是错误的。out 意味着调用者的 object[] 变量将指向一个新的 object[]。但这里并不是这种情况。 - Matthew Flaschen

0

你可以返回一个包含多个数组的数组或者一个包含两个数组的对象。然而,看起来这两个数组中的值应该是相关的,所以你应该使用一个包含两个值的对象数组。

顺便说一下:我永远不会使用 Float,而 float 我也会避免使用(因为它只精确到小数点后6位),我建议使用 int、long 或 double。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接