I have a class of Student. The class has String name
, int studentId
and int studentScore
. I want to compare the students in ArrayList<Student> students
according to the studentscore. This means if "student 1" and "student 2" has the same amount of studentscore then both of their ranks will be the same. I have a function where I set The rank. But I'm unsure how to compare everything in the arraylist.
When I search for comparing int values I get the results:
How to properly compare two Integers in Java?
I think the best solution will be to use comparator class function. But Im unsure how to do this because I'm unsure of the comparator classes capability. I was think of for looping getting a player by that loop then for looping again and comparing. But this doesnt seem like a good solution.
I want this result:
Say that the array of students contains (name,studentscore) is:
(kim, 12), (werder, 20), (ben, 32), (sara, 12)
I want the rank of the student to be (If ASC order):
kim: rank = 1
werder: 2
ben: 3
sara: 1
You should use java Stream (Java 8).
Better way to do this.
You can found a really good exemple at : http://www.leveluplunch.com/java/tutorials/007-sort-arraylist-stream-of-objects-in-java8/
You may first students by score using Comparator.somparing()
comparator, then iterate over sorted list and apply ranks, as follows:
Collection<Student> students = // ... your collection of students
// copy students to a new List
List<Student> ordered = new ArrayList<>(students);
// sort by score
Collections.sort(ordered, Comparator.comparing(Student::getScore));
// set rank 1 to first item, i. e. having the lowest score
int rank = 1;
ordered.get(0).setRank(rank);
for (int i = 1; i < ordered.size(); i++) {
// increment rank only if score changed
// in order to apply same ranks to same scores
if (ordered.get(i).getScore() != ordered.get(i - 1).getScore())
rank++;
ordered.get(i).setRank(rank);
}
If you'd need lower ranks to be assigned to higher scores, just apply .reversed()
to a comparator:
Collections.sort(ordered, Comparator.comparing(Student::getScore).reversed());
To create a comparator in Java prior 1.8, you need to instantiate an anonymous Comparator
where .compare()
method is implemented:
Comparator<Student> cmp = new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getScore().compareTo(s2.getScore());
}
}
There are two ways to deal with your issue. You can make your class to implement Comparable interface, and then it would have a method compareTo()
. But then you will need to worry that your compareTo()
method is consistent with equals()
method. That means that you will need to override your equals()
and hashCode()
methods. That might be a bit too much.
The other way about it is to create your own Comparator that would implement an interface Comporator. All you will need to do is to impllement method int compare(T o1, T o2)
and then just use Collections
's public static void sort(List list,
Comparator c) method.
Once you sort your array it will be easy just to iterate through it and assign appropriate ranks
If I understand you correctly, you want to be able to sort your ArrayList<Student>
based on the studentScore
.
You can have the student class implement Comparable()
public class Student implements Comparable<Student> {
private String name;
private int studentId;
private int studentScore;
public int compareTo(Contact other) {
return studentScore.compareTo(other.studentScore);
}
Then you can do
ArrayList<Student> students = new ArrayList<Student>;
// Insert you students into the array
// students.add(someStudent)
Collections.sort(students);
Note that this is the Comparable
interface which requires you to implement the method compareTo()
. You only need the Comparator
interface if you want to impose a total ordering, for example to order objects that do not have some natural ordering.
The students should then be sorted in ascending order in the list, so that the first element in the list the "smallest".