The use and difference between Comparable interface and Comparator interface

One: Custom sorting of collections:

TreeSet: The underlying data structure is a red-black tree with customizable sorting rules

Construction method:
public TreeSet();
public TreeSet(Comparator c);

The sorting methods using TreeSet collection are:

Method 1: When calling the parameterless constructor

1. Let the generic Stu class of Treeset implement the interface Comparable,

And the generic type of Comparable must be consistent with the generic type of TreeSet, otherwise an exception will be reported:

Stu cannot be cast to java.lang.Comparable

2. When the Stu class implements the interface Comparable,

Must override the method of overriding the interface int compareTo(Object obj)

Ascending: this-obj

Descending order: obj-this

Take a look at the code to achieve the effect:

public class Test03 {
public static void main(String[] args) {
\t\t
//Method 1: Class implements Comparable<E> interface
Set<Stu> set = new TreeSet<>();
\t\t
Collections.addAll(set, new Stu("Peng Yuyan","Xi'an"), new Stu("Wu Jing","Ningxia Hui Autonomous Region"), new Stu("Nicolas Cage" ,"San Francisco"));
\t
for (Stu stu : set) {
System.out.println(stu);
}
}
}

class Stu implements Comparable<Stu>{
private String name;
private String addr;
\t
//Override and rewrite the int compareTo(Stu o) method
@Override
public int compareTo(Stu o) {
//Ascending order based on name length
return this.name.length() - o.name.length();
\t\t
// Or in descending order according to the length of the address
// return o.getAddr().length() - this.getAddr().length();
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((addr == null) ? 0 : addr.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Stu other = (Stu) obj;
if (addr == null) {
if (other.addr != null)
return false;
} else if (!addr.equals(other.addr))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

@Override
public String toString() {
return "Stu [name=" + name + " , addr=" + addr + "]";
}

public Stu(String name, String addr) {
super();
this.name = name;
this.addr = addr;
}
publicStu() {
super();
// TODO Auto-generated constructor stub
}

public String getName() {
return name;
}
public String getAddr() {
return addr;
}
public void setName(String name) {
this.name = name;
}
public void setAddr(String addr) {
this.addr = addr;
}

}

This is based on name length, ascending order

Output results:

Stu [name=Wu Jing, addr=Ningxia Hui Autonomous Region]
Stu [name=Eddie Peng, addr=Xi’an]
Stu [name=Nicolas Cage, addr=San Francisco]

Method Method2: Use the parameterized construction method and pass in a parameter of Comparator c

1. Create an object of the Comparator abstract class through an anonymous inner class

2. Override and rewrite the interface method int compare(Object o1, Object o2); in the anonymous inner class

? Ascending order: o1-o2

? Descending order: o2-o1

Code implementation effect:
Two comparators of public class Test03_Set {
public static void main(String[] args) {
\t\t
//Method 2: Anonymous inner class, pass in Comparator<> comparator
Set<Stu> set = new TreeSet<>( new Comparator<Stu>() {
@Override
public int compare(Stu o1,Stu o2) {
//Ascending order based on name length
// return o1.getName().length() - o2.getName().length();
\t\t\t\t
//Or in descending order according to the length of the address
return o2.getAddr().length() - o1.getAddr().length();
}
});
\t\t
\t\t
Collections.addAll(set, new Stu("Peng Yuyan","Xi'an"), new Stu("Wu Jing","Ningxia Hui Autonomous Region"), new Stu("Nicolas Cage" ,"San Francisco"));
\t
for (Stu stu : set) {
System.out.println(stu);
}
\t\t
}
}


class Stu {
private String name;
private String addr;
\t
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((addr == null) ? 0 : addr.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Stu other = (Stu) obj;
if (addr == null) {
if (other.addr != null)
return false;
} else if (!addr.equals(other.addr))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

@Override
public String toString() {
return "Stu [name=" + name + " , addr=" + addr + "]";
}

public Stu(String name, String addr) {
super();
this.name = name;
this.addr = addr;
}
publicStu() {
super();
// TODO Auto-generated constructor stub
}

public String getName() {
return name;
}
public String getAddr() {
return addr;
}
public void setName(String name) {
this.name = name;
}
public void setAddr(String addr) {
this.addr = addr;
}
}

Here in descending order according to address length

Output results:

Stu [name=Wu Jing, addr=Ningxia Hui Autonomous Region]
Stu [name=Nicolas Cage, addr=San Francisco]
Stu [name=Eddie Peng, addr=Xi’an]

Note:

If the generic type of the collection not only implements the Comparable interface, but also uses parameterized construction to create a Comparator object,

Then the principle of proximity: select the sorting rule in Comparator

Two: Custom sorting of arrays

If the type of the array is a type provided by JDK:

If the type of the array is a basic data type, you can directly use the Arrays.sort() method to sort. Default ascending order

If you want to sort in descending order, you need to convert the basic data type into a reference data type, then use the Arrays.sort() method to pass in a Comparator type object, and override int compare(T o1, T o2 )method

Or directly call the method Comparator . reverseOrder(); in the interface

Here I use double [] as an example:

 double[] arr = {3.2, 0.1, -2, 1.5, 4.7, 2.8};
\t\t
//Ascending order
Arrays.sort(arr);
System.out.println("Ascending order:" + Arrays.toString(arr));
\t\t
\t\t

//descending order
//First wrap the basic data type into a reference data type
Double[] boxedArr = new Double[arr.length];
\t\t
for (int i = 0; i < arr.length; i + + ) {
boxedArr[i] = arr[i];
}
\t\t
//Descending order Method 1: Pass in Comparator
Arrays.sort( boxedArr, new Comparator<Double>() {
@Override
public int compare(Double o1, Double o2) {
return (int)(o2-o1);
}
});
\t\t
//Descending order method two:
// Arrays.sort(boxedArr, Comparator.reverseOrder());
\t\t
System.out.println("Descending:" + Arrays.toString(boxedArr));

Output results:

Ascending order: [-2.0, 0.1, 1.5, 2.8, 3.2, 4.7]
Descending order: [4.7, 2.8, 3.2, 1.5, 0.1, -2.0]

If the type of the array is a custom type:

You can let the class implement the Comparable interface and then override the int compareTo(T o) method

public class Test04_Array custom sorting {
public static void main(String[] args) {
\t\t
//Array custom type sorting
Stu[] stuArr = new Stu[] {new Stu("Peng Yuyan","Xi'an"),
                    new Stu("Wu Jing","Ningxia Hui Autonomous Region"), new Stu("Nicolas Cage","San Francisco")};
\t\t
//Sort according to the sorting rules in the class
Arrays.sort(stuArr);
\t\t
for (Stu stu : stuArr) {
System.out.println(stu);
}
}
}

class Stu implements Comparable<Stu>{
private String name;
private String addr;

@Override
public int compareTo(Stu o) {
//Ascending order by name
// return this.name.length() - o.name.length();
\t\t
//According to address descending order
return o.addr.length() - this.addr.length();
}

@Override
public String toString() {
return "Stu [name=" + name + " , addr=" + addr + "]";
}

public Stu(String name, String addr) {
super();
this.name = name;
this.addr = addr;
}
publicStu() {
super();
// TODO Auto-generated constructor stub
}

public String getName() {
return name;
}
public String getAddr() {
return addr;
}
public void setName(String name) {
this.name = name;
}
public void setAddr(String addr) {
this.addr = addr;
}
}

Output results: in descending order by address

Stu [name=Wu Jing, addr=Ningxia Hui Autonomous Region]
Stu [name=Nicolas Cage, addr=San Francisco]
Stu [name=Eddie Peng, addr=Xi’an]

② The anonymous inner class creates a Comparator object and overrides the int compT o1, T o2) method

public class Test04_Array custom sorting {
public static void main(String[] args) {
\t\t
//Array custom type sorting
Stu[] stuArr = new Stu[] {new Stu("Peng Yuyan","Xi'an"),
                    new Stu("Wu Jing","Ningxia Hui Autonomous Region"), new Stu("Nicolas Cage","San Francisco")};
\t\t
//Anonymous inner class creates Comparator
Arrays.sort( stuArr , new Comparator<Stu>() {
@Override
public int compare(Stu o1,Stu o2) {
//Ascending order by name
return o1.getName().length() - o2.getName().length();
//In descending order by address
// return o2.getAddr().length() - o1.getAddr().length();
}
} );

for (Stu stu : stuArr) {
System.out.println(stu);
}
}
}


classStu{
private String name;
private String addr;

@Override
public String toString() {
return "Stu [name=" + name + " , addr=" + addr + "]";
}

public Stu(String name, String addr) {
super();
this.name = name;
this.addr = addr;
}
publicStu() {
super();
// TODO Auto-generated constructor stub
}

public String getName() {
return name;
}
public String getAddr() {
return addr;
}
public void setName(String name) {
this.name = name;
}
public void setAddr(String addr) {
this.addr = addr;
}
}

Output results: ascending order by name

Stu [name=Wu Jing, addr=Ningxia Hui Autonomous Region]
Stu [name=Eddie Peng, addr=Xi’an]
Stu [name=Nicolas Cage, addr=San Francisco]

Likes and comments are welcome! ! !