Implements Comparable to get alphabetical sort wit

2020-07-09 02:28发布

问题:

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!

回答1:

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


回答2:

return name.compareTo(otherObject.name);

String already implements Comparable so you don't need do to anything.



回答3:

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


回答4:

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