Using comparator with multiple comparators - java

I can use all the simple comparators in this code for sorting just fine but not the ComplexComparator. I couldn't figure it out how to code to get it to work properly. Any suggestion / explanation would be appreciated.
This is my main program:
package pkgTest;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Student[] students = new Student[6];
students[0] = new Student("Pete", 1989, 3.6);
students[1] = new Student("Tomas", 1989, 3.9);
students[2] = new Student("Helen", 1990, 3.6);
students[3] = new Student("Steve", 1991, 3.7);
students[4] = new Student("Natalie", 1993, 3.7);
students[5] = new Student("John", 1992, 4.0);
NameComparator byName
= new NameComparator();
BirthDateComparator byBirthDate
= new BirthDateComparator();
AverageComparator byAverage
= new AverageComparator();
ComplexComparator complexSorting
= new ComplexComparator(byName,
byAverage);
System.out.println("===============");
System.out.println("Before sorting:");
System.out.println("===============");
for (Student student : students) {
System.out.println(student.getName()
+ " // " + student.getBirthDate()
+ " // " + student.getAverage());
}
Arrays.sort(students, complexSorting);
System.out.println("==============");
System.out.println("After sorting:");
System.out.println("==============");
for (Student student : students) {
System.out.println(student.getName()
+ " // " + student.getBirthDate()
+ " // " + student.getAverage());
}
}
}
Here are the rest of the classes:
package pkgTest;
public class Student {
private String name;
private int birthDate;
private double average;
public Student(String name, int birthDate,
double average) {
this.name = name;
this.birthDate = birthDate;
this.average = average;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getBirthDate() {
return this.birthDate;
}
public void setBirthDate(int birthDate) {
this.birthDate = birthDate;
}
public double getAverage() {
return this.average;
}
public void setAverage(double average) {
this.average = average;
}
}
package pkgTest;
import java.util.Comparator;
public class ComplexComparator implements Comparator<Student> {
public ComplexComparator(Comparator<Student> one,
Comparator<Student> another) {
}
#Override
public int compare(Student one, Student another) {
/*This is the part that
I just couldn't figure
it out to get it work.
It has to work no matter
which 2 of the 3 comparators
I use to set the input
parameters of ComplexComparator.
I have to make it work by
modifying only this part of
the code.*/
}
}
package pkgTest;
import java.util.Comparator;
public class AverageComparator implements Comparator<Student> {
#Override
public int compare(Student one, Student another) {
if (one.getAverage()
< another.getAverage()) {
return -1;
} else if (one.getAverage()
== another.getAverage()) {
return 0;
} else {
return +1;
}
}
}
package pkgTest;
import java.util.Comparator;
public class BirthDateComparator implements Comparator<Student> {
#Override
public int compare(Student one, Student another) {
if (one.getBirthDate()
< another.getBirthDate()) {
return -1;
} else if (one.getBirthDate()
== another.getBirthDate()) {
return 0;
} else {
return +1;
}
}
}
package pkgTest;
import java.util.Comparator;
public class NameComparator implements Comparator<Student> {
#Override
public int compare(Student one, Student another) {
return one.getName().
compareToIgnoreCase(another.getName());
}
}

You will have to modify the class ComplexComparator like the following, at least...
import java.util.Comparator;
public class ComplexComparator implements Comparator<Student> {
private Comparator<Student> comparatorOne;
private Comparator<Student> comparatorTwo;
public ComplexComparator(Comparator<Student> one,
Comparator<Student> another) {
this.comparatorOne = one;
this.comparatorTwo = another;
}
#Override
public int compare(Student one, Student another) {
// make a first comparison using comparator one
int comparisonByOne = comparatorOne.compare(one, another);
// check if it was 0 (items equal in that attribute)
if (comparisonByOne == 0) {
// if yes, return the result of the next comparison
return comparatorTwo.compare(one, another);
} else {
// otherwise return the result of the first comparison
return comparisonByOne;
}
}
}
For more than two Comparators you will need a List of them (or another overloaded constructor) and a loop that keeps a certain order of comparisons.
EDIT
For your additional requirement regarding sorting orders, this may be helpful:
public class ComplexComparator implements Comparator<Student> {
private Comparator<Student> comparatorOne;
private Comparator<Student> comparatorTwo;
private boolean orderOneAscending = true;
private boolean orderTwoAscending = true;
/**
* Constructor without any sort orders
* #param one a comparator
* #param another another comparator
*/
public ComplexComparator(Comparator<Student> one, Comparator<Student> another) {
this.comparatorOne = one;
this.comparatorTwo = another;
}
/**
* Constructor that provides the possibility of setting sort orders
* #param one a comparator
* #param orderOneAscending sort order for comparator one
* (true = ascending, false = descending)
* #param another another comparator
* #param orderTwoAscending sort order for comparator two
* (true = ascending, false = descending)
*/
public ComplexComparator(Comparator<Student> one, boolean orderOneAscending,
Comparator<Student> another, boolean orderTwoAscending) {
this.comparatorOne = one;
this.comparatorTwo = another;
this.orderOneAscending = orderOneAscending;
this.orderTwoAscending = orderTwoAscending;
}
#Override
public int compare(Student one, Student another) {
int comparisonByOne;
int comparisonByAnother;
if (orderOneAscending) {
/* note that your lexicographical comparison in NameComparator
returns a negative integer if the String is greater!
If you take two numerical Comparators, the order will
turn into the opposite direction! */
comparisonByOne = comparatorOne.compare(another, one);
} else {
comparisonByOne = comparatorOne.compare(one, another);
}
if (orderTwoAscending) {
comparisonByAnother = comparatorTwo.compare(one, another);
} else {
comparisonByAnother = comparatorTwo.compare(another, one);
}
if (comparisonByOne == 0) {
return comparisonByAnother;
} else {
return comparisonByOne;
}
}
}
Just play around with the values and try some modifications to get familiar with common problems concerning comparing and sorting.
I hope this will be helpful...

Modify Your ComplexComparator as below
public class ComplexComparator implements Comparator<Student> {
private List<Comparator<Student>> listComparators;
#SafeVarargs
public ComplexComparator(Comparator<Student>... comparators) {
this.listComparators = Arrays.asList(comparators);
}
#Override
public int compare(Student studen1, Student studen2) {
for (Comparator<Student> comparator : listComparators) {
int result = comparator.compare(studen1, studen2);
if (result != 0) {
return result;
}
}
return 0;
}
}

Here is a generic complex comparator you can use for any type of of objects (based on this answer):
public class ComplexComparator<T> implements Comparator<T> {
private List<Comparator<T>> listComparators;
#SafeVarargs
public ComplexComparator(Comparator<T>... comparators) {
listComparators = Arrays.asList(comparators);
}
#Override
public int compare(T o1, T o2) {
for (Comparator<T> comparator : listComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
There will be an unchecked cast warning when you use it, but you can suppress that, given that it will cast successfully as long as your class is comparable.
#SuppressWarnings("unchecked")
Comparator<MyClass> comparator = new ComplexComparator(
MyClass.ComparatorA,
MyClass.ComparatorB);
Collections.sort(mySet, comparator);
If anyone knows a way how to not get that warning, please comment and I update the answer.

I am not sure exactly how you want the solution to be presented. But from my understanding, if you want to do it by just putting code in the commented place, you can just try putting code like this.
Assuming the case when after comparing name, if same, you intend to move to average.
public int compare(Student StOne, Student StAnother) {
if(one.compare(Sone, Sanother)==0) {
return another.compare(StOne, StAnother);
}
else
return one.compare(StOne, StAnother);
}
But for this, you need to ensure that the values you take in the constructor of ComplexComparator (byName, byAverage) should be the instance variables of the class, and need to be initialized in the constructor.
public class ComplexComparator implements Comparator<Student> {
private Comparator<Student> one;
private Comparator<Student> another;
public ComplexComparator(Comparator<Student> one,
Comparator<Student> another) {
this.one=one;
this.another=another;
}
#Override
public int compare(Student one, Student another) {
//code given above
} }

Related

implementing sort and search methods for arraylist of objects in Java

I know basic programming but I'm new to OOP and Java. I'm trying to short and search ArrayList of objects. I know there are many ways to do it but I like two-approach here with collections,
Java List.contains(Object with field value equal to x) and here Sort ArrayList of custom Objects by property
codes are working when they are inside the main class but I wanted to move them in student class and calling over my own sort and search methods. The sort function still works but the search returns wrong index integers. I couldn't find what I m missing. The complete code is below.
/* implementation of binary search found at
https://stackoverflow.com/questions/18852059/
and sort solution at
https://stackoverflow.com/questions/2784514/
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class test {
static ArrayList<Student> course = new ArrayList<>();
public static void main(String[] args) {
System.out.print("Enter name to search: ");
Scanner input = new Scanner(System.in);
String stName = input.nextLine();
course.add(new Student("will", 353429, 13.2));
course.add(new Student("joe", 353430, 12.1));
course.add(new Student("bill", 353431, 14.9));
course.add(new Student("jim", 353432, 15.3));
course.add(new Student("jack", 353473, 11.2));
course.add(new Student("jean", 353439, 16.8));
course.add(new Student("jill", 353333, 14.9));
course.add(new Student("jane", 353432, 15.7));
course.add(new Student("john", 353421, 10.6));
course.add(new Student("ben", 353438, 16.0));
course.add(new Student("dave", 353529, 14.9));
course.add(new Student("jim", 352989, 15.3));
course.add(new Student("doug", 353178, 11.2));
sortStudents();
/* // search part works when its here , inside main class
int idx = Collections.binarySearch(course, new Student( stName ), new Comparator<Student>() {
#Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
*/
int idx = searchStudent( stName );
System.out.println("Sorted list");
for (int cnt=0;cnt<course.size();cnt++){
System.out.println(cnt + " "+ course.get(cnt).toString());
}
if (idx>0){
System.out.println(stName +" found on line: " + idx);
}else{
System.out.println(" Not in the list" +idx);
}
}
static void sortStudents(){
Collections.sort(course,Student.sortByName);
}
static int searchStudent(String nm){
return Collections.binarySearch(course, new Student(nm));
}
static class Student implements Comparable<Student>{
private String name;
private int age;
private double points;
public Student(String nm) { this.name = nm; } // constructor
public Student(String nm, int n, double p) { // constructor
this.name = nm;
this.age = n;
this.points = p; }
public String getName(){ return name; }
// but search code fails when moved here
public static Comparator<Student> binarySearch = new Comparator<Student>() {
#Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
};
public static Comparator<Student> sortByName = new Comparator<Student>() {
#Override
public int compare(Student obj1, Student obj2) {
//sort in ascending order
return obj1.name.compareTo(obj2.name);
//sort in descending order
//return obj2.name.compareTo(obj1.name);
}
};
#Override
public int compareTo(Student o) {
return 0;
}
#Override
public String toString() {
return "Name:" + name + ", Age:" + age;
}
}
}
Problem
That's because of your compareTo, because you didn't implement how may be compared the Student between them, you only implemented a name comparator, and this is used by the Collections.binarySearch
#Override
public int compareTo(Student o) {
return 0;
}
You could fix with explicit Comparator
static int searchStudent(String nm) {
return Collections.binarySearch(course, new Student(nm), Student.sortByName);
}
Improve
Also Comparator<Student> binarySearch is same as Comparator<Student> sortByName, no reason to get 2 things doing same.
You need to understand that, either
you need to a Comparator to tell how to order objects
make the object Comparable so it knows ITSELF how to order it with the others
Here you did both, that isn't useful, remove the Comparators definitions
Fix
So only a compareTo method will do the job
#Override
public int compareTo(Student o) {
int diff = this.name.compareTo(o.name);
if (diff != 0) {
return diff;
}
return Integer.compare(this.age, o.age);
}
It can be simplified with a Comparator that allows some method chaining. Note that it is private, it shouldn't be used outside the class manually, AS the class now knows by itself how to order elements
static private Comparator<Student> studComp = Comparator.comparing(Student::getName)
.thenComparing(Student::getAge);
#Override
public int compareTo(Student o) {
return studComp.compare(this, o);
}
Giving in the main class
static void sortStudents() {
course.sort(Comparator.naturalOrder());
}
static int searchStudent(String nm) {
return Collections.binarySearch(course, new Student(nm));
}

Sort ArrayList via specific Value in ArrayList Object?

I have a Score System that I want to create, in which there is a list of players ranging their score from highest to lowest.
My PlayerObject.class Class:
public class PlayerObject {
private String playerName;
private int playerScore;
public int getScore() {
return this.playerScore;
}
public String getName() {
return this.playerName;
}
public void setNameAndScore(String givenName, int givenScore) {
this.playerName = givenName;
this.playerScore = givenScore;
}
}
My Array:
ArrayList<PlayerObject> allPlayers = new ArrayList<PlayerObject>();
Any idea how I can sort each player in the array list based on their playerScore attribute?
There are a lot of ways you can do it. First this is PlayerObject class:
public class PlayerObject implements Comparable<PlayerObject> {
private String playerName;
private int playerScore;
public PlayerObject(String playerName, int playerScore) {
this.playerName = playerName;
this.playerScore = playerScore;
}
public String getPlayerName() {
return playerName;
}
public int getPlayerScore() {
return playerScore;
}
#Override
public int compareTo(PlayerObject o) {
return Integer.compare(playerScore, o.playerScore);
}
}
And this is how you can sort it:
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
List<PlayerObject> players = new ArrayList<>(2);
players.add(new PlayerObject("player1", 2));
players.add(new PlayerObject("player2", 4));
// if PlayerObject implements Comparable<PlayerObject>
Collections.sort(players);
// or if you want explicit Comparator
players.sort(new Comparator<PlayerObject>() {
#Override
public int compare(PlayerObject o1, PlayerObject o2) {
return Integer.compare(o1.getPlayerScore(), o2.getPlayerScore());
}
});
// or you can use lambda if you use Java 8
players.sort((o1, o2) -> Integer.compare(o1.getPlayerScore(), o2.getPlayerScore()));
// or even more concise
players.sort(Comparator.comparingInt(PlayerObject::getPlayerScore));
}
}
Here is a documentation that will help you:
Comparable
Comparator
One of the possible way to implement Comparable in your PlayerObject class and override compareTo method.
public class PlayerObject implements Comparable<PlayerObject> {
...
...
#Override
public int compareTo(PlayerObject o) {
// You can interchange the return value (-1 and 1) to change the sorting order
if(getPlayerScore() > o.getPlayerScore())
{
return -1
}
else if(getPlayerScore() < o.getPlayerScore())
{
return 1;
}
return 0;
}
}
With java 8, you can do it that way, without implementing any interface :
allPlayers = allPlayers.stream()
.sorted(Comparator.comparingInt(PlayerObject::getScore))
.collect(Collectors.toList());
Or just :
Collections.sort(allPlayers, Comparator.comparingInt(PlayerObject::getScore))
Consider using comparator.
Classic one
Collections.sort(allPlayers, new Comparator<PlayerObject>() {
#Override
public int compare(PlayerObject p1, PlayerObject p2) {
return p1.getScore().compareTo(p2.getScore());
}
});
And with java-8 Lambda support
allPlayers.sort(
(PlayerObject p1, PlayerObject p2) -> p1.getScore().compareTo(h2.getScore()));

Collections.sort - I have created 2 user define objects [both are of different types] and then add into arraylist , then I have tried to sort it

Expected Result of code is ClassCastException but Actual Result :- [Person with pid- 1 - a1-name, Person with pid- 2 - c2-name, Sorting.Employee#cdfc9c, Sorting.Employee#1837697]
Person class:
package Sorting;
public class Person implements Comparable<Person> {
private int pid;
private String pname;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
#Override
public String toString() {
return "Person with pid- " + getPid() + " - " + getPname();
}
#Override
public int compareTo(Person p) {
return this.pid - p.pid;
}
}
Employee class:
package Sorting;
public class Employee implements Comparable {
#Override
public int compareTo(Object o) {
return 0;
}
}
SortingofObjects class:
package Sorting;
import java.util.ArrayList;
import java.util.Collections;
public class SortingofObjects {
public static void main(String[] args) {
Person p1 = new Person();
p1.setPid(1);
p1.setPname("a1-name");
Person p2 = new Person();
p2.setPid(2);
p2.setPname("c2-name");
Employee e1 = new Employee();
Employee e2 = new Employee();
ArrayList a = new ArrayList();
a.add(p1);
a.add(p2);
a.add(e1);
a.add(e2);
Collections.sort(a);
System.out.println(a);
}
}
Collections.sort does not call compareTo on every pair in the List, just enough pairs to sort the List. As an example, run this code:
public class Test implements Comparable<Test> {
public static void main(String[] args) {
List<Test> list = new ArrayList<Test>();
list.add(new Test(1));
list.add(new Test(2));
list.add(new Test(3));
list.add(new Test(4));
Collections.sort(list);
}
private final int number;
Test(int number) {
this.number = number;
}
#Override
public int compareTo(Test that) {
System.out.println(this + ".compareTo(" + that + ")");
return 0;
}
#Override
public String toString() {
return "" + number;
}
}
The output is
2.compareTo(1)
3.compareTo(2)
4.compareTo(3)
Since your List is in the order Person, Person, Employee, Employee, the only combination that would throw a ClassCastException, namely
Person.compareTo(Employee)
never occurs. If your List contained an Employee before a Person it would throw an exception.
If it just so happens that the sorting algorithm used only compares Employees to Persons, and not the other way around, then it'll never throw, because Employee.compareTo accepts any Object. You just got lucky, more or less.

Java, how to use compareTo to sort an Arraylist

Im trying to figure out how to sort an ArrayList using comparable, my code looks like this:
public class playerComparsion{
public static void main(String[] args){
ArrayList<Object> list = new ArrayList<Object>();
Player p1 = new Players(1,92,Zlatan);
Player p2 = new Players(2,92,Hazard);
Player p3 = new Players(1,82,Klose);
list.add(p1);
list.add(p2);
list.add(p3);
}
}
class Players implements Comparable{
int position;
String name;
int rating;
public Players(int i, int j, String string) {
this.position=i;
this.rating=j;
this.name=string;
}
public void getRating() {
System.out.println(this.rating);
}
public void getPos() {
System.out.println(this.position);
}
public void getName() {
System.out.println(this.name);
}
#Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}
I want to sort the Arraylist based on the attribute rating. I suppose I should use the compareTo function but I have no idea how, can someone help me?
Instead of making Player implement Comparable, you get more flexibility by implementing Comparator<Player> classes. For example:
class PlayerComparatorByRating implements Comparator<Player> {
#Override
public int compare(Player o1, Player o2) {
return o1.getRating() - o2.getRating();
}
}
class PlayerComparatorByName implements Comparator<Player> {
#Override
public int compare(Player o1, Player o2) {
return o1.getName().compareTo(o2.getName());
}
}
After all, Player has multiple fields, it's easy to imagine that sometimes you might want to order players differently. A great advantage of this approach is the single responsibility principle: a Player class does only one thing, encapsulates player data. Instead of adding one more responsibility (sorting), it's better to move that logic in another class.
You could use these comparators with Collections.sort, for example:
Collections.sort(list, new PlayerComparatorByRating());
System.out.println(list);
Collections.sort(list, new PlayerComparatorByName());
System.out.println(list);
Extra tips
Your class seems to be named Players. It's better to rename to Player.
The getName, getRating, getPos methods should not return void and print the result, but return the field values instead.
Use better names for the constructor arguments, for example:
Player(int position, int rating, String name) {
this.position = position;
this.rating = rating;
this.name = name;
}
Use the right type of list to store players:
List<Player> list = new ArrayList<Player>();
Please format your code properly. Any IDE can do that.
Suggested implementation
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Player {
private int position;
private int rating;
private final String name;
Player(int position, int rating, String name) {
this.position = position;
this.rating = rating;
this.name = name;
}
public int getRating() {
return rating;
}
public int getPos() {
return position;
}
public String getName() {
return name;
}
#Override
public String toString() {
return String.format("%s:%d:%d", name, position, rating);
}
}
class PlayerComparatorByRating implements Comparator<Player> {
#Override
public int compare(Player o1, Player o2) {
return o1.getRating() - o2.getRating();
}
}
class PlayerComparatorByName implements Comparator<Player> {
#Override
public int compare(Player o1, Player o2) {
return o1.getName().compareTo(o2.getName());
}
}
public class PlayerComparatorDemo {
public static void main(String[] args){
List<Player> list = new ArrayList<Player>();
Player p1 = new Player(1, 92, "Zlatan");
Player p2 = new Player(2, 92, "Hazard");
Player p3 = new Player(1, 82, "Klose");
list.add(p1);
list.add(p2);
list.add(p3);
Collections.sort(list, new PlayerComparatorByRating());
System.out.println(list);
Collections.sort(list, new PlayerComparatorByName());
System.out.println(list);
}
}
Don't use a raw type with Comparable. Instead, use Comparable<Players>. This way, you have direct access to the object you care about without having to cast from Object.
The sample compareTo would be this:
public int compareTo(Player other) {
return rating - other.getRating();
}
Then, you would actually have to...sort it, using Collections.sort().
Collections.sort(list);
The reason for Comparable<Players> is that Comparable itself is defined as taking a generic type T.
Try this.
public class Comparator_Test {
public static void main(String[] args) {
ArrayList<Players> list = new ArrayList<Players>();
Players p1 = new Players(1,92,"Zlatan");
Players p2 = new Players(2,92,"Hazard");
Players p3 = new Players(1,82,"Klose");
list.add(p1);
list.add(p2);
list.add(p3);
PlayerComparator comparator = new PlayerComparator();
System.out.println(list);
Collections.sort(list, comparator);
System.out.println(list);
}
}
class Players {
int position;
String name;
int rating;
public Players(int i, int j, String string) {
this.position=i;
this.rating=j;
this.name=string;
}
public void getRating() {
System.out.println(this.rating);
}
public void getPos() {
System.out.println(this.position);
}
public void getName() {
System.out.println(this.name);
}
public String toString() {
return rating + "";
}
}
class PlayerComparator implements Comparator<Players> {
#Override
public int compare(Players o1, Players o2) {
if(o1.rating > o2.rating) {
return 1;
}
if(o1.rating < o2.rating) {
return -1;
}
return 0;
}
}

Implements Comparable to get alphabetical sort with Strings

I would like an object to be comparable (to use it in a TreeSet in that case).
My object got a name field and I would like it to be sorted by alphabetical order.
I thought first that I could use the unicode value of the string and simply do a subtraction, but then AA would be after Ab for example…
Here’s how I started :
public final class MyObject implements Comparable<MyObject> {
private String name;
public MyObject(String name) {
this.name = name;
}
public String name() {
return name;
}
#Override
public int compareTo(MyObject otherObject) {
return WHAT DO I PUT HERE ?;
}
}
Thanks to those who will help,
have a nice day!
You are overthinking the problem. Strings have their own natural ordering, which is alphabetic, so you can just use the String.compareTo like this:
#Override
public int compareTo(MyObject otherObject) {
return this.name.compareTo(otherObject.name);
}
return name.compareTo(otherObject.name);
String already implements Comparable so you don't need do to anything.
I think you want something like this
package mine;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MyObject {
private String name;
public MyObject(String name) {
this.name = name;
}
public MyObject() {
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "MyObject [name=" + name + "]";
}
public static void main(String[] args){
List<MyObject> l = new ArrayList<>();
l.add(new MyObject("Ab"));
l.add(new MyObject("AA"));
l.add(new MyObject());
Collections.sort(l, new Comparator<MyObject>(){
#Override
public int compare(MyObject o1, MyObject o2) {
if (o1.name == null && o2.name == null){
return 0;
}else if (o1.name == null){
return -1;
}else if (o2.name == null){
return 1;
}else{
return o1.name.toUpperCase().compareTo(o2.name.toUpperCase());
}
}
});
System.out.println(l);
}
}
Exist so many way which preferred before it. But for maintain better compatibility, performance and avoiding runtime exceptions (such as NullPointerException) use best practices which is
For String
#Override
public int compareTo(OtherObject o) {
return String.CASE_INSENSITIVE_ORDER.compare(this.name,o.name);
}
For int, double float (to avoid boxing and unboxing which issue for performance use below comparators)
// with functional expression
Comparator.compareInt, Comparator.compareDouble, Comparator.compareFloat
// or with static compare method
/**
* Integer
*/
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
/**
* Double
*/
public int compareTo(Double anotherDouble) {
return Double.compare(value, anotherDouble.value);
}
/**
* Float
*/
public int compareTo(Float anotherFloat) {
return Float.compare(value, anotherFloat.value);
}
/**
* Objects
*/
public int compareTo(Object other) {
return Object.compare(value, other.value);
}
[Effective Java Item 14: Consider implement Comparable]
Finally, whenever you implement a value class that has a sensible ordering, you should have a class implements Comparable interface so that its instances can be easily sorted, searched and used in comparison-based collections. When comparing field values in the implementations of the compareTo methods, avoid the use of the < and > operators. Instead, use the static compare methods in the boxed primitive classes or the comparator construction methods in the Comparator interface

Categories