java 基础-Comparable和Comparator的用法

Java中Comparable和Comparator的用法

对于自己定义的数据结构,进行排序时,需要我们给予他一定的排序规则,这就涉及到了Java中的两个常用的接口Comparable和Comparator的实现。

Comparable --内部比较器

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

Comparator --外部比较器

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 c);
        Collections.sort(List list, Comparator c);
        TreeSet(Comparator comparator);
        TreeMap(Comparator 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 + "]";
	}
}

你可能感兴趣的:(java基础)