Не уверен, как сортировать ArrayList на основе частей Объектов в этом ArrayList (Java) - PullRequest
0 голосов
/ 08 марта 2012

У меня есть класс Sorts, который сортирует (на основе сортировки вставкой, которая была направлением назначения) любой ArrayList любого типа, прошедшего через него, и использует сортировку вставки для лексикографической сортировки элементов в списке:

public class Sorts
{
public static void sort(ArrayList objects)
{
    for (int i=1; i<objects.size(); i++)
    {
        Comparable key = (Comparable)objects.get(i);
        int position = i;

        while (position>0 && (((Comparable)objects.get(position)).compareTo(objects.get(position-1)) < 0))
        {
            objects.set(position, objects.get(position-1));
            position--;
        }   
        objects.set(position, key);
    }
}
}

В одном из моих других файлов я использую метод (который позже вызывается в main), который сортирует объекты типа Owner, и мы должны отсортировать их по фамилии (если они совпадают, то по имени):

Указания: "Сортировать список владельцев по фамилии от А до Z. Если несколько владельцев имеют одинаковую фамилию, сравните их имена. Этот метод вызывает метод сортировки, определенный в классе Сортировки."

Сначала я подумал о том, чтобы получить фамилию каждого владельца в цикле for, добавить ее во временный ArrayList типа string, вызвать Sorts.sort () и затем снова добавить ее обратно вArrayList ownerList:

public void sortOwners() {
    ArrayList<String> temp = new ArrayList<String>();
    for (int i=0; i<ownerList.size(); i++)
        temp.add(((Owner)ownerList.get(i)).getLastName());
    Sorts.sort(temp);
    for (int i=0; i<temp.size(); i++)
        ownerList.get(i).setLastName(temp.get(i));
}

Я думаю, это был неправильный подход к нему, так как он не сортируется при компиляции.

Теперь я думаю, что мне следует создать два ArrayLists (один firstName, другой LastName) и сказать, что в цикле for, если (lastName одно и то же), тогда сравните firstName, но яЯ не уверен, что мне понадобятся два ArrayList для этого, поскольку это кажется излишне сложным.

Так что вы думаете?

Редактировать: я добавляю версию CompareTo (Object other):

public int compareTo(Object other)
{
    int result = 0;
    if (lastName.compareTo(((Owner)other).getLastName()) < 0)
        result = -1;
    else if (lastName.compareTo(((Owner)other).getLastName()) > 0)
        result = 1;
    else if (lastName.equals(((Owner)other).getLastName()))
    {
        if (firstName.compareTo(((Owner)other).getFirstName()) < 0)
            result = -1;
        else if (firstName.compareTo(((Owner)other).getFirstName()) > 0)
            result = 1;
        else if (firstName.equals(((Owner)other).getFirstName()))
            result = 0;
    }
    return result;
}

Ответы [ 4 ]

1 голос
/ 08 марта 2012

Я думаю, что объект должен реализовывать метод compareTo, который следует обычному Comparable контракту - поиск сортировки по нескольким полям. Вы правы, что два списка не нужны.

0 голосов
/ 08 марта 2012

Поскольку у вас есть ArrayList объектов, обычно мы используем метод Collections.sort() для выполнения этой задачи. Обратите внимание на подпись метода:

public static <T extends Comparable<? super T>> void sort(List<T> list)

Здесь важно то, что все сортируемые объекты должны реализовывать интерфейс Comparable, который позволяет сравнивать объекты в числовом виде. Для пояснения, у объекта Comparable есть метод с именем compareTo со следующей подписью:

int compareTo(T o)

Теперь мы подошли к хорошей части. Когда объект имеет значение Comparable, его можно сравнить численно с другим объектом. Давайте посмотрим на образец вызова.

String a = "bananas";
String b = "zebras";
System.out.println(a.compareTo(b));

Результат будет -24. Семантически, поскольку зебры находятся дальше в конце словаря по сравнению с бананами , мы говорим, что бананы сравнительно меньше , чем зебры ( не так далеко в словаре).

Так что решение должно быть ясным сейчас. Используйте compareTo для сравнения ваших объектов таким образом, что они отсортированы по алфавиту. Поскольку я показал вам, как сравнивать строки, надеюсь, вы должны иметь общее представление о том, что нужно писать.

Получив числовые сравнения, вы будете использовать класс Collections для сортировки списка. Но поскольку у вас есть свои собственные возможности сортировки, отсутствие доступа к ним не является большой потерей. Вы все еще можете сравнить численно, что было целью с самого начала! Так что это должно прояснить необходимые шаги, теперь, когда я их изложил.

0 голосов
/ 08 марта 2012

Так как это домашнее задание, вот несколько подсказок:

  1. Предполагая, что цель состоит в том, чтобы реализовать алгоритм сортировки самостоятельно, вы обнаружите, что намного проще (и более производительно) извлечь элементы списка в массив, отсортировать массив и затем перестроить список (или создать новый).

  2. Если это не цель, тогда посмотрите на класс Collections.

  3. Реализация пользовательского Comparator или изменение класса объекта для реализации Comparable.

0 голосов
/ 08 марта 2012

Если у вас есть контроль над кодом Owner для начала, измените код так, чтобы он реализовывал Comparable. Его метод compareTo() выполняет тест lastName / firstName, описанный в задании. Ваш sortOwners() метод передаст List<Owner> напрямую Sorts.sort().

Если у вас нет контроля над Owner, создайте подкласс Owner, который реализует Comparable. Назовите это OwnerSortable или тому подобное. Он принимает обычный Owner объект в своем конструкторе и просто делегирует все методы, кроме compareTo(), обернутому объекту. Его compareTo() будет работать, как указано выше. Ваш метод sortOwners() создаст новый List<OwnerSortable> из списка Owner. Затем он может передать это на Sorts.sort().

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