ArrayList Выбор сортировки

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

ArrayList:

ArrayList<Movie3> myMovies = new ArrayList<Movie3>();
myMovies.add(new Movie3("The Muppets Take Manhattan", 2001, "Columbia Tristar"));
myMovies.add(new Movie3("Mulan Special Edition", 2004, "Disney"));
myMovies.add(new Movie3("Shrek 2", 2004, "Dreamworks"));
myMovies.add(new Movie3("The Incredibles", 2004, "Pixar"));
myMovies.add(new Movie3("Nanny McPhee", 2006, "Universal"));
myMovies.add(new Movie3("The Curse of the Were-Rabbit", 2006, "Aardman"));
myMovies.add(new Movie3("Ice Age", 2002, "20th Century Fox"));
myMovies.add(new Movie3("Lilo & Stitch", 2002, "Disney"));
myMovies.add(new Movie3("Robots", 2005, "20th Century Fox"));
myMovies.add(new Movie3("Monsters Inc.", 2001, "Pixar"));

Сортировка:

    int i, k, posmin;
    int temp;
    for (i = b.size()-1; i >= 0; i--) {
        posmin = 0;
        for (k=0; k <= i; k++) {
            if (b.get(k).getYear() <= b.get(posmin).getYear()) posmin = k;
        }
        temp = b.get(i).getYear();
        b.get(i).setTitle(b.get(posmin).getTitle());
        b.get(i).setYear(b.get(posmin).getYear());
        b.get(i).setStudio(b.get(posmin).getStudio());

        b.get(posmin).setYear(temp);
    }

РЕДАКТИРОВАТЬ: Это код, на котором я его основал - он сортирует заголовки, и он прекрасно работает.

            int i, k, posmax;
            String temp;
            for (i = b.size()-1; i >= 0; i--) {
                posmax = 0;
                for (k=0; k <= i; k++) {
                    if (b.get(k).getTitle().compareTo(b.get(posmax).getTitle()) < 0) posmax = k;
                }
                temp = b.get(i).getTitle();
                b.get(i).setTitle(b.get(posmax).getTitle());
                b.get(i).setYear(b.get(posmax).getYear());
                b.get(i).setStudio(b.get(posmax).getStudio());

                b.get(posmax).setTitle(temp);
            }

3 ответа

Решение

Быстрое исправление: вам нужно поменять все данные в объекте, а не только год.

Например, когда во втором раунде в вашем алгоритме сортировки вы будете менять местами Movie3("The Muppets Take Manhattan", 2001, "Columbia Tristar") а также new Movie3("Robots", 2005, "20th Century Fox"), Поскольку вы меняете только годы (установите все данные на последний, а только год верните в неупорядоченный список), то это закончится Movie3("The Muppets Take Manhattan", 2005, "Columbia Tristar") а также Movie3("The Muppets Take Manhattan", 2001, "Columbia Tristar"), Поэтому ваш Robots фильм исчез.

Лучшее решение: вы можете поменять местами ссылку вместо того, чтобы устанавливать все данные в объекте.

Поскольку в ArrayList хранятся ссылки, вы можете просто поменять их местами.

Movie3 tmp = b.get(i);
b.set(i, b.get(posmin));
b.set(posmin, tmp);

Было бы лучше в этом случае.

Если вы хотите, чтобы вся тройка была отсортирована, вам нужно также сохранить значения для "title" и "studio", а не только для "year" - в противном случае эти значения будут потеряны. Вы можете добиться этого, создав еще две временные переменные (в приведенном ниже примере: tempTitle и tempStudio). Обратите внимание, что я переименовал ваш "temp" в "tempYear" для лучшего обзора.

int i, k, posmin;
    int tempYear;
    String tempTitle, tempStudio;
    for (i = b.size()-1; i >= 0; i--) {
        posmin = 0;
        for (k=0; k <= i; k++) {
            if (b.get(k).getYear() <= b.get(posmin).getYear()) posmin = k;
        }
        tempYear = b.get(i).getYear();
        tempTitle = b.get(i).getTitle();
        tempStudio = b.get(i).getStudio();

        b.get(i).setYear(b.get(posmin).getYear());
        b.get(posmin).setYear(tempYear);

        b.get(i).setTitle(b.get(posmin).getTitle());
        b.get(posmin).setTitle(tempTitle);

        b.get(i).setStudio(b.get(posmin).getStudio());
        b.get(posmin).setStudio(tempStudio);

    }

Гораздо лучший способ сделать это - создать компаратор и передать его Collections.sort(..) функция.

Скажи твой Movie3 выглядит примерно так

public static class Movie3 {
    public Movie3(String title, int year, String studio) {
        this.title = title;
        this.year = year;
        this.studio = studio;
    }

    public String toString() {
        return title + " (" + year + ") [" + studio + "]";
    }

    String title;
    int year;
    String studio;
}

Вот как вы могли бы объявить comparator и передать его в функцию сортировки. Запустите это в вашем текущем ArrayList с любыми изменениями, которые вы считаете необходимыми.

Comparator<Movie3> comp = new Comparator<Movie3>() {
    @Override
    public int compare(Movie3 a, Movie3 b) {
        // compare names
        if(a.title.compareTo(b.title) != 0)
            return -1*(a.title.compareTo(b.title));

        // same name, compare years
        if(a.year < b.year)
            return 1;
        else if(a.year > b.year)
            return -1;

        // same name, year, compare studio
        return -1*(a.studio.compareTo(b.studio));
    }
};
List<Movie3> list = new ArrayList<Movie3>();
Collections.sort(list, comp);

Для тебя myMovies список, это то, что он должен выводить:

[Маппет-шоу Манхэттен (2001) [Колумбия Тристар], Невероятные (2004) [Pixar], Проклятие кролика-оборотня (2006) [Aardman], Шрек 2 (2004) [Dreamworks], Роботы (2005) [ 20th Century Fox], няня Макфи (2006) [Universal], Mulan Special Edition (2004) [Disney], Monsters Inc. (2001) [Pixar], Lilo & Stitch (2002) [Disney], Ледниковый период (2002) [20th Century Fox]]

Другие вопросы по тегам