2009-06-20 3 views
3

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

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

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

ответ

4

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

EDIT: Для решения проблемы сортировки вы можете использовать любой алгоритм сортировки для сортировки height массива. Единственное различие заключается в том, что когда вы меняете два элемента в процессе сортировки height, вы также должны поменять соответствующие элементы в массиве weight.

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

EDIT: Как правило, при использовании параллельных массивов, это означает, что вы не используете объекты должным образом. Чтобы следовать вашему примеру, у вас должен быть класс Comparable Person с свойствами высоты и веса. Конечно, как сказал Мехрдад, вы можете вручную реализовать алгоритм сортировки параллельного массива, но это действительно не идеально.

0

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

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

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

+0

Это неправильно. out будет означать, что переменная object [] вызывающего объекта указала бы на новый объект []. Это не то, что здесь происходит. –

1

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

Один из способов избежать этой проблемы состоит в том, чтобы инкапсулировать высоту/вес в классе, чтобы они всегда были в синхронизации. На рисунке 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

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

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

Смежные вопросы