Сортировка массивов в Java - PullRequest
3 голосов
/ 20 июня 2009

Я хочу передать 2 массива функции в Java и отсортировать их в вызывающей функции. Как я могу использовать функцию для достижения этой цели?

Я мог бы заставить функцию возвращать объект с двумя массивами, но есть ли не объектно-ориентированное решение для этого?

РЕДАКТИРОВАТЬ: В этой конкретной ситуации я не могу использовать встроенную функцию Array.sort в Java. Допустим, 2 массива - это рост и вес. Они имеют одинаковую длину, и один и тот же индекс соответствует одному и тому же росту и весу человека в обоих массивах. Я хочу отсортировать массив высот в порядке возрастания, при этом сортируя массив весов, соответствующий массиву высот. Так что использование функции сортировки испортит отношения между двумя массивами.

Ответы [ 5 ]

5 голосов
/ 20 июня 2009
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);
}

РЕДАКТИРОВАТЬ: как правило, когда вы используете параллельные массивы, это означает, что вы не используете объекты должным образом. Чтобы следовать вашему примеру, у вас должен быть класс Comparable Person со свойствами роста и веса. Конечно, как сказал Mehrdad, вы можете вручную реализовать алгоритм сортировки параллельных массивов, но на самом деле он не идеален.

4 голосов
/ 20 июня 2009

Когда вы передаете массив функции, он не копируется. Просто ссылка на него копируется и передается функции, которая будет указывать на то же место. Вам просто нужно отсортировать массивы на месте.

РЕДАКТИРОВАТЬ: Чтобы решить актуальную проблему сортировки, вы можете использовать любой алгоритм сортировки для массива height. Единственное отличие состоит в том, что когда вы меняете два элемента в процессе сортировки height, вы также должны менять соответствующие элементы в массиве weight.

1 голос
/ 21 июня 2009

Хотя использование двух отдельных массивов и синхронизация их сортировки возможны, использование этого типа решения может привести к ошибкам, которые впоследствии будет трудно найти. Например, если синхронизация между массивами не работает правильно, то неправильные веса могут совпадать с высотами.

Один из способов избежать такого рода проблем - инкапсулировать рост / вес в классе, чтобы они всегда были синхронизированы. На рисунке 1 есть класс с именем Person, который имеет рост, вес и имя в качестве атрибутов. Если вы всегда собираетесь сортировать по возрастанию по высоте, то вы можете реализовать метод compareTo(), как показано на рисунке 1.

На рисунке 2 показан тестовый пример junit, демонстрирующий, как сортировать список Person s. Тестовый пример также демонстрирует, как сортировать по весу. В обоих случаях никогда не возникает проблема синхронизации между весом и ростом, поскольку сортировка выполняется для объекта, который их инкапсулирует.

Рисунок 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 голосов
/ 21 июня 2009

Вы можете вернуть массив массивов или объект, который содержит два массива. Однако, похоже, что значения в двух массивах должны быть коррелированы, поэтому у вас должен быть один массив объектов, который содержит два значения.

Кстати: я бы не использовал Float и плавающих, которых я бы также избегал (так как он точен только в 6 местах), я бы предложил использовать int, long или double.

0 голосов
/ 20 июня 2009

Итак, вы хотите, чтобы функция A вызывала функцию B. Затем B сортирует массивы, а A возвращает два отсортированных массива?

Поскольку параметры являются ссылочными в Java, если вы измените свои объекты в B, A увидит измененные версии.

В C # это можно даже явно сказать с помощью ключевого слова out, которое сообщает всем, что функция изменит параметр out.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...