Reputation: 21901
I need to sort an ArrayList of films best rated to worse (5 best - 1 worst). I am using Collections.sort() but the list comes out the same. what am i doing wrong
films.add(new Film().setRating(1));
films.add(new Film().setRating(2.5));
films.add(new Film().setRating(3.5));
films.add(new Film().setRating(4));
films.add(new Film().setRating(5));
films.add(new Film().setRating(1));
films.add(new Film().setRating(2));
films.add(new Film().setRating(3));
films.add(new Film().setRating(4));
Collections.sort(films, new Comparator<Film>() {
@Override
public int compare(Film o1, Film o2) {
final double film1 = o1.getRating();
final double film2 = o2.getRating();
return film1 > film2? 1
: film1 < film2? -1 : 0;
}
});
Upvotes: 5
Views: 13060
Reputation: 552
There are two ways of solving this problem
Implementing compare method of comparator interface in second parameter of Collections.sort method.
Ensuring your class implements Comparable interface and then implementing compareTo method.
Here is the code for both solutions.
public class ComparableTest implements Comparable < ComparableTest > {
String name;
int marks;
@Override
public int compareTo(ComparableTest o) {
if (this.marks > o.marks)
return 1;
return -1;
}
public ComparableTest(String name, int marks) {
this.name = name;
this.marks = marks;
}
public String getName() {
return name;
}
public int getMarks() {
return marks;
}
}
package program;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class TempList {
public static void main(String[] args) {
/*************************************************/
/****************Assigning Values*****************/
/*************************************************/
String[] names = {
"A",
"B",
"C",
"D",
"E"
};
List < ComparableTest > objects = new LinkedList < > ();
/*************************************************/
/****************Printing Values******************/
/*************************************************/
for (String name: names) {
objects.add(new ComparableTest(name, new Random().nextInt(100)));
}
System.out.println("Before Sorting");
for (ComparableTest object: objects) {
System.out.println(object.name + " " + object.marks);
}
/*************************************************/
/*************Sorting based on marks**************/
/*************************************************/
Collections.sort(objects);
System.out.println("\nSorting based on Marks");
for (ComparableTest object: objects) {
System.out.println(object.name + " " + object.marks);
}
/*************************************************/
/*************Sorting based on names**************/
/*************************************************/
System.out.println("\nSorting based on Names");
Collections.sort(objects, new Comparator < ComparableTest > () {
@Override
public int compare(ComparableTest o1, ComparableTest o2) {
if (o1.name.compareTo(o2.name) < 1) {
return 1;
}
return -1;
}
});
for (ComparableTest object: objects) {
System.out.println(object.name + " " + object.marks);
}
}
}
Upvotes: 0
Reputation: 12225
Your code works just fine on my computer, the following:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortFilms {
public static void main(final String ... args) {
new SortFilms().sort();
}
public void sort() {
final List<Film> films = new ArrayList<Film>();
films.add(new Film(1));
films.add(new Film(2.5));
films.add(new Film(3.5));
films.add(new Film(4));
films.add(new Film(5));
films.add(new Film(1));
films.add(new Film(2));
films.add(new Film(3));
films.add(new Film(4));
Collections.sort(films, new Comparator<Film>() {
@Override
public int compare(Film o1, Film o2) {
final double film1 = o1.getRating();
final double film2 = o2.getRating();
return film1 > film2? 1
: film1 < film2? -1 : 0;
}
});
System.out.println(films);
}
private class Film {
private final double rating;
public Film(double rating) {
this.rating = rating;
}
public String toString() {
return "" + rating;
}
public Double getRating() {
return rating;
}
}
}
Procudes:
[1.0, 1.0, 2.0, 2.5, 3.0, 3.5, 4.0, 4.0, 5.0]
Upvotes: 1
Reputation: 61198
Using the Double.compare
method works fine:
public static void main(String[] args) throws IOException, ClassNotFoundException {
final List<Film> films = new ArrayList<>();
films.add(new Film().setRating(1));
films.add(new Film().setRating(2.5));
films.add(new Film().setRating(3.5));
films.add(new Film().setRating(4));
films.add(new Film().setRating(5));
films.add(new Film().setRating(1));
films.add(new Film().setRating(2));
films.add(new Film().setRating(3));
films.add(new Film().setRating(4));
System.out.println(films);
Collections.sort(films, new Comparator<Film>() {
@Override
public int compare(Film o1, Film o2) {
return Double.compare(o1.getRating(), o2.getRating());
}
});
System.out.println(films);
}
Output:
[1.0, 2.5, 3.5, 4.0, 5.0, 1.0, 2.0, 3.0, 4.0]
[1.0, 1.0, 2.0, 2.5, 3.0, 3.5, 4.0, 4.0, 5.0]
The Film
I used:
private static final class Film {
double rating;
public double getRating() {
return rating;
}
public Film setRating(double rating) {
this.rating = rating;
return this;
}
@Override
public String toString() {
return Double.toString(rating);
}
}
I would suggest using Double.compare
rather than your version, or even o1.getRating - o2.getRating
.
It's either that or your Film
implementation is wrong - maybe the setter in your example doesn't set anything?
Upvotes: 5
Reputation: 3191
Use the folowing method in Double
instead:
public static int compare(double d1, double d2){}
or like this:
class Film implements Comparable<Film>{
double rating;
@Override
public int compareTo(Film o) {
return Double.compare(rating, o.rating);
}
}
Upvotes: 2