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. String
s 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