对于自己定义的数据结构,进行排序时,需要我们给予他一定的排序规则,这就涉及到了Java中的两个常用的接口Comparable和Comparator的实现。
public interface Comparable
(1) 该接口只有一个int compareTo(T o)方法,compareTo返回值-1、0、1。
(2) 如根据某个类创建的数组或列表(List)需要排序,则该类可以继承 Comparable接口并实现 comparaTo()方法。
(3) 排序写法:
Arrays.sort(array);
Collections.sort(list);
(4) 继承了Comparable的类,在用这个类创建TreeSet 和 TreeMap(键)时可以不用指定比较器Comparator。(如果既没有继承Comparable类,也没有指定比较器Compartor则元素加不进去,会报错。在set中的add方法会调用treemap中的put方法。先判断是否有比较器Comparator,在判断是否继承了Comparable)
在TreeSet和TreeMap中的put源码
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
在数组、列表、TreeSet 和TreeMap中的应用
package comparable和comparator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* Comparable 内部比较器
* @author Administrator
*
*/
public class ComparableTest {
public static void main(String[] args) {
//数组
Student[] stus = {new Student("wendy",21),new Student("Jack",22)};
Arrays.sort(stus);
for (Student student : stus) {
System.out.println(student);
}
//列表
List<Student> list = new ArrayList<Student>();
list.add(new Student("wendy",21));
list.add(new Student("Jack",23));
System.out.println(list);
Collections.sort(list);
System.out.println(list);
//TreeSet
TreeSet<Student> tree = new TreeSet<Student>();
tree.add(new Student("wendy",21));
tree.add(new Student("jack",23));
System.out.println(tree);
//TreeMap
TreeMap<Student,String> map = new TreeMap<>();
map.put(new Student("jack",23), "1");
map.put(new Student("wendy",21), "2");
System.out.println(map);
}
}
class Student implements Comparable<Student>{
private String stuName;
private int age;
public Student(String stuName, int age) {
super();
this.stuName = stuName;
this.age = age;
}
@Override
public String toString() {
return "Student [stuName=" + stuName + ", age=" + age + "]";
}
@Override
public int compareTo(Student stu) {
return this.age - stu.age;
//return this.stuName.compareTo(stu.stuName);
}
}
public interface Comparator
我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。
(1) 该接口有一个int compare(T o,T o2)方法,compare返回值-1、0、1。还有一个equals()方法。
(2) 如根据某个类创建的数组或列表(List)需要排序,如果该类没有继承Comparable接口,则需要自己定义一个继承Comparator的比较器。在TreeSet或者TreeMap(键)中,向集合中添加该类的元素,如果该类没有继承Comparable接口,也需要在创建集合的时候(构造函数中)传入一个Comparator的比较器。
(3) 排序写法:
Arrays.sort(T[] a, Comparator super T> c);
Collections.sort(List list, Comparator super T> c);
TreeSet(Comparator super Work> comparator);
TreeMap(Comparator super Work> comparator);
package comparable和comparator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* Comparator 外部比较器
* @author Administrator
*
*/
public class ComparatorTest {
public static void main(String[] args) {
//数组
Work[] works = {new Work("wendy",21),new Work("Jack",23)};
for (Work work : works) {
System.out.println(work);
}
/**
* 创建比较器方式一:匿名内部类
*/
Arrays.sort(works, new Comparator<Work>(){
@Override
public int compare(Work o1, Work o2) {
return o1.getAge() - o2.getAge();
}
});
/**
* 创建比较器方式二:自定义一个类继承Comparator
*/
Arrays.sort(works, new MyComparator());
for (Work work : works) {
System.out.println(work);
}
//list集合
List<Work> list = new ArrayList<>();
list.add(new Work("wendy",21));
list.add(new Work("jack",20));
Collections.sort(list, new MyComparator());
System.out.println("list:" + list);
//TreeSet
TreeSet<Work> set = new TreeSet<>(new MyComparator());
set.add(new Work("wendy",34));
set.add(new Work("jack",21));
System.out.println("set:" + set);
//TreeMap
TreeMap<Work,String> map = new TreeMap<>(new Comparator<Work>(){
@Override
public int compare(Work o1, Work o2) {
return o1.getAge()-o2.getAge();
}
});
map.put(new Work("wendy",23),"1");
map.put(new Work("jack",20),"2");
System.out.println("map:" + map);
}
}
//自定义比较器
class MyComparator implements Comparator<Work>{
@Override
public int compare(Work o1, Work o2) {
return o1.getStuName().compareTo(o2.getStuName());
}
}
class Work {
private String stuName;
private int age;
public String getStuName() {
return stuName;
}
public int getAge() {
return age;
}
public Work(String stuName, int age) {
super();
this.stuName = stuName;
this.age = age;
}
@Override
public String toString() {
return "Work [stuName=" + stuName + ", age=" + age + "]";
}
}