目录
如果现在要想为一组对象进行排序,那么必须有一个可以区分出对象大小的关系操作,而这个操作在Java之中就是利用比较器完成的。
1.1、常用比较器:Comparable
如果要为对象指定比较规则,那么对象所在的类必须实现Comparable接口,下面首先来看一下这个接口的定义:
public interface Comparable<T> {
public int compareTo(T o);
}
根据文档的要求:要排序的数组所在的类一定要实现此接口,此接口返回的是int型数据,而用户覆写此方法的时候只需要返回三种结果:1(>0)、-1(<0)、0(=0)即可。
实现比较器
import java.util.Arrays;
class Person implements Comparable <Person> {
private String name ;
private int age ;
public Person(String name,int age) {
this.name = name ;
this.age = age ;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]\n";
}
@Override
public int compareTo(Person o) {
if (this.age > o.age) {
return 1;
} else if (this.age < o.age) {
return -1;
} else {
return 0;
}
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Person per[] = new Person[] { new Person("张三", 20),
new Person("李四", 19), new Person("王五", 21) };
Arrays.sort(per) ; // 排序
System.out.println(Arrays.toString(per));
}
}
以后不管是何种情况下,只要牵扯到对象数组排序的操作,永远都是比较器Comparable。
1.2、Binary Tree,二叉树
二叉树是一种排序的基本的数据结构,而如果要想为多个对象进行排序,那么就必须可以区分出对象的大小,那么就必须依靠Comparable接口完成。
二叉树的基本原理:取第一个元素作为根节点,之后每一个元素的排列要求:如果比根节点小的数据放在左子树,如果比根节点大的数据放在右子树,在输出的时候采用中序遍历(左-根-右)的方式完成。
但是,不管是何种方式操作,一定要记住,这种数据结构的实现永远都需要依靠节点类,而这个时候的节点类要保存两个子节点:左、右。
class Student implements Comparable<Student> {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]\n";
}
@Override
public int compareTo(Student o) {
if (this.age > o.age) {
return -1;
} else if (this.age < o.age) {
return 1;
} else {
return 0;
}
}
}
class BinaryTree {
@SuppressWarnings("rawtypes")
private class Node {
private Comparable data;
private Node left;
private Node right;
public Node(Comparable data) {
this.data = data;
}
@SuppressWarnings("unchecked")
public void addNode(Node newNode) {
if (this.data.compareTo(newNode.data) < 0) {
if (this.left == null) { // 没有左子树
this.left = newNode;
} else {
this.left.addNode(newNode);
}
} else {
if (this.right == null) {
this.right = newNode;
} else {
this.right.addNode(newNode);
}
}
}
public void printNode() {
if (this.left != null) {
this.left.printNode();
}
System.out.println(this.data);
if (this.right != null) {
this.right.printNode();
}
}
}
private Node root; // 根节点
public void add(Student data) {
if (data == null) {
return;// 返回调用处
}
Node newNode = new Node(data); // 将数据封装为节点
if (this.root == null) { // 没有根节点
this.root = newNode;
} else { // 保存到合适的位置
this.root.addNode(newNode);
}
}
public void print() {
if (this.root != null) {
this.root.printNode();
}
}
}
public class BinaryTreeDemo {
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
tree.add(new Student("张三", 20));
tree.add(new Student("李四", 19));
tree.add(new Student("王五", 21));
tree.print();
}
}
如果不是笔试之中出现,基本上就出现不了了,所以以上的代码,作为了解,清楚就行了,实际上也别用。
1.3、挽救的比较器
之前使用的Comparable实际上是在一个类定义的时候就已经具备的功能了,但是如果说现在一个类已经定义完成了。
范例:已经定义好了一个Person类
class Person {
private String name ;
private int age ;
public Person(String name,int age) {
this.name = name ;
this.age = age ;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]\n";
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
这个类在设计之初并没有考虑到排序的要求,可是后来又需要进行排序,但是以上的类已经无法修改了,那么如何使用Arrays.sort()排序呢?为了解决这样的问题,在java里面又提供了另外一个比较器接口:java.util.Comparator接口,这个接口的定义如下:
public interface Comparator<T> {
public int compare(T o1, T o2);
public boolean equals(Object obj);
}
在compare()方法上存在了两个参数用于比较大小,而要想使用这个接口,需要单独定义一个比较规则类。
范例:专门为Person类补救一个比较规则类
class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
if (o1.getAge() > o2.getAge()) {
return 1;
} else if (o1.getAge() < o2.getAge()) {
return -1;
} else {
return 0;
}
}
}
而后如果要进行排序的话,依然使用Arrays类的sort()方法:public static <T> void sort(T[] a, Comparator<? super T> c)
范例:实现排序
public class TestDemo {
public static void main(String[] args) throws Exception {
Person per[] = new Person[] { new Person("张三", 20),
new Person("李四", 19), new Person("王五", 21) };
Arrays.sort(per, new PersonComparator()); // 排序
System.out.println(Arrays.toString(per));
}
}
很明显,使用Comparator要比Comparable麻烦许多,所以以后别使它。
面试题:请解释Comparable和Comparator的区别?(请解释两种比较器的区别)
· java.lang.Comparable是在一个类定义的时候默认实现好的接口,里面只有一个compareTo()方法;
· java.util.Comparator是需要单独定义一个比较的规则类,里面有两个方法;compare()、equals()。
本文介绍了Java中的比较器Comparable接口及其在对象排序中的作用,详细讲解了二叉树作为排序数据结构的基础原理,并探讨了当类无法修改时如何使用Comparator接口进行排序。同时,文章对比了Comparable和Comparator的区别。
371

被折叠的 条评论
为什么被折叠?



