This is the sixth day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021.

A previous article, “Common Uses of Map in Java are here” (juejin.cn/post/702668…) Use Map to install a class:

public class TestMap2 {
    public static void main(String[] args) {

        Employee e1 = new Employee(Awesome!."Fang".66666);
        Employee e2 = new Employee(667."Zhang".9999999); // Because he is crazy
        Employee e3 = new Employee(668."' uncle".36888);

        Map<Integer, Employee> map = new TreeMap<>();
        map.put(Awesome!, e1);
        map.put(667, e2);
        map.put(668, e3);
        Employee emp = map.get(Awesome!); // Return the objectSystem.out.println(emp.getName()); }}Copy the code

Classes defined in this case can then be combined with the Comparable interface to implement custom ordering of maps. It’s also a wow moment for Python enthusiasts to learn Java.

Let’s start with the Comparable interface

Here’s what the official document says:

Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

That is, compare the o object here in compareTo(T o) with a specific object:

  • Returns a negative integer indicating thatthis.value < o.value;
  • Returns zero, indicatingthis.value = o.value;
  • Positive integer, indicatingthis.value > o.value.

I’m using the mathematical notation for the plus and minus sign function, so negative integers are -1, 0 is 0,1 is positive.

In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -10, or 1 according to whether the value of expression is negative, zero or positive.

How do you define it

public class TestTreeSet {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<>();

        set.add(300);
        set.add(200);
        set.add(138);
        set.add(250);

        for (Integer m: set) {
            System.out.println(m);
        }

        Set<Emp2> set2 = new TreeSet<>();
        set2.add(new Emp2(100."hh".66));
        set2.add(new Emp2(110."hh3".686));
        set2.add(new Emp2(15."hh1".56));

        for(Emp2 m: set2) { System.out.println(m); }}}class Emp2 implements Comparable<Emp2> {
    int id;
    String name;
    double salary;

    @Override
    public String toString(a) {
        return "id=" + id +
                ", name='" + name +
                ", salary=" + salary;
    }

    public Emp2(int id, String name, double salary) {
        super(a);this.id = id;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public int compareTo(Emp2 e) {
        / / < 0 small; 0 =; > 0 and a positive number
        if (this.salary >e.salary) {
            return 1;
        } else if(this.salary < e.salary) {
            return -1;
        } else {
            if (this.id > e.id) {
                return 1;
            } else if (this.id < e.id) {
                return -1;
            } else {
                return 0; }}}}Copy the code

The running results are as follows:You can see that when you add elements, it’s out of order, but when you print this TreeSet, it’s out of order!

detour

Get meng my place, but also by the source to explain.

Set

set2 = new TreeSet<>(); This must be “TreeMap” or “TreeSet” for sorting to work.

Here is the Structure view of TreeMap (command+7 in IDEA) :

You can see that it’s useful for this compare() interface.

final int compare(Object k1, Object k2) {
    return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
        : comparator.compare((K)k1, (K)k2);
}
Copy the code

Comparable is used here again.

This part of the HashMap looks like this:onlycomparableClassFor(Object):Class<? >compareComparables(Class<? >, Object, Object):int.

Double-click again and open it for a look:

comparableClassFor(Object):Class
:


/** * Returns x's Class if it is of the form "class C implements * Comparable
      
       ", else null. */
      
staticClass<? > comparableClassFor(Object x) {if (x instanceofComparable) { Class<? > c; Type[] ts, as; ParameterizedType p;if ((c = x.getClass()) == String.class) // bypass checks
            return c;
        if((ts = c.getGenericInterfaces()) ! =null) {
            for (Type t : ts) {
                if ((t instanceofParameterizedType) && ((p = (ParameterizedType) t).getRawType() == Comparable.class) && (as = p.getActualTypeArguments()) ! =null &&
                    as.length == 1 && as[0] == c) // type arg is c
                    returnc; }}}return null;
}
Copy the code

compareComparables(Class
, Object, Object) : int:


/** * Returns k.compareTo(x) if x matches kc (k's screened comparable * class), else 0. */
@SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable
static int compareComparables(Class
        kc, Object k, Object x) {
    return (x == null|| x.getClass() ! = kc ?0 :
            ((Comparable)k).compareTo(x));
}
Copy the code

Has nothing to do with how it’s putting elements in order.

Little distinctive knowledge ask questions

Will you use the Comparable interface in your projects? Or is most of the processed data processed upstream, sorted by the sort function in SQL?