0

I am trying to do a selection sort with the years on an ArrayList of movies, and with this code, I get the years in the right descending order, but the titles and studio names do not correspond with the year in the output. How can I get the titles, studio names, and years to be together?

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

Sorting:

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

EDIT: This is the code I based it off of - it sorts the titles, and it works perfectly fine.

            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);
            }
Stephanie Fu
  • 79
  • 1
  • 9
  • In the three almost identical lins (Title, Year, Studio) you appear to have flipped `i` and `posmin`. One of them is not needed in fact , since the Year is set with the two lines that surround the three lines. – roadrunner66 Mar 16 '16 at 02:28
  • 2
    You can use `Collections.sort` with a custom Comparator instead of having to work out the sorting yourself. Take a look at this link for better explanation: http://stackoverflow.com/questions/2535124/how-to-sort-an-arraylist-of-objects-by-a-property – Ceelos Mar 16 '16 at 02:29
  • @roadrunner66, I tried that, and it came out with the wrong output. – Stephanie Fu Mar 16 '16 at 02:32
  • @Ceelos, this is part of an assignment that is teaching selection sorting, and I did the title sorting correctly, but I don't know why the year sorting is not working. – Stephanie Fu Mar 16 '16 at 02:33
  • Could you please add your example data (just a few lines) so i'ts easier to test? – roadrunner66 Mar 16 '16 at 02:36
  • Stephanie - I don't know for sure, but I expect that the person who set you this assignment >>wants<< you to debug your own code. After all, debugging code is one of the basic skills that every programmer needs. Now is a good time to learn it ... – Stephen C Mar 16 '16 at 02:38
  • @roadrunner66, I added the ArrayList. I went through every line and sorted through an imaginary arraylist, and I don't see anything wrong with it in my head, but the title and studio output doesn't come out right. – Stephanie Fu Mar 16 '16 at 02:43
  • Stephanie - Since "hand execution" isn't working for you, try using the debugger in your IDE. Seriously, it is in your own interest that you solve this for yourself. The learning is more important than the answer (or the marks). – Stephen C Mar 16 '16 at 02:48

3 Answers3

0

Quick fix: You need to swap all data in the Object, not only the year.

For example, when the 2nd round in your sorting algorithm, you will result in swapping Movie3("The Muppets Take Manhattan", 2001, "Columbia Tristar") and new Movie3("Robots", 2005, "20th Century Fox"). Because you only swap the years (set all data to the last but only set year back to the unordered list), so it will end with Movie3("The Muppets Take Manhattan", 2005, "Columbia Tristar") and Movie3("The Muppets Take Manhattan", 2001, "Columbia Tristar"). Therefore, your Robots movie is disappeared.

Better solution: You can swap the reference instead of set all data in the Object.

Since there are references stored in the ArrayList, you can just swap those references to swap them.

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

It would be better in this case.

Nier
  • 638
  • 7
  • 15
  • Thanks! A question though - do you know why the code worked for the title sorting, but not for the year sorting? – Stephanie Fu Mar 16 '16 at 03:09
  • @StephanieFu I don't think your title sorting is correct. If you run your title sorting code, you will find that your year of "Robots" movie changed from 2005 to 2004. Same problem in title sorting code. – Nier Mar 16 '16 at 03:13
  • Oh, ok - in my output, most of the years matched up so I thought it was sorted right. Thank you so much! – Stephanie Fu Mar 16 '16 at 03:15
0

If you want the whole triple to be sorted, you have to save the values for "title" and "studio" too and not only the one for "year" - otherwise these values are lost. You can achieve that by creating two more temporary variables (in the example below: tempTitle and tempStudio). Notice, that I renamed your "temp" into "tempYear for a better overview.

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

    }
OneShotDev
  • 31
  • 4
0

A much better way of doing this would be to create a comparator and pass it to the Collections.sort(..) function.

Say, your Movie3 looks something like this.

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

This is how you could declare a comparator and pass it to the sort function. Run this on your current ArrayList with any changes you deem required.

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

For your myMovies list, this is what it should output:

[The Muppets Take Manhattan (2001) [Columbia Tristar], The Incredibles (2004) [Pixar], The Curse of the Were-Rabbit (2006) [Aardman], Shrek 2 (2004) [Dreamworks], Robots (2005) [20th Century Fox], Nanny McPhee (2006) [Universal], Mulan Special Edition (2004) [Disney], Monsters Inc. (2001) [Pixar], Lilo & Stitch (2002) [Disney], Ice Age (2002) [20th Century Fox]]

Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43