一、Arrays类
“java.util.Arrays.sort()”是一个数组排序操作,实际上这一个操作就是调用了java.util包中Arrays类的sort()方法完成的,而Arrays是一个数组操作的工具类(数组一般使用较少,所以此工具类意义不大)。
范例:使用Arrays类
import java.util.Arrays; public class TestDemo { public static void main(String[] args) throws Exception { int dataA[] = new int[] { 1, 2, 3 }; int dataB[] = new int[] { 1, 2, 3 }; System.out.println(Arrays.equals(dataA, dataB)); Arrays.fill(dataA, 9); System.out.println(Arrays.toString(dataA)); } }
随着数组的使用减少,此类的操作也越来越少。
下面来观察在Arrays类之中存在的一个方法:
- 对象数组排序:public static void sort(Object[] a);
范例:实现排序
import java.util.Arrays; class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } } public class TestDemo { public static void main(String[] args) throws Exception { Person per[] = new Person[] { new Person("张三", 20), new Person("李四", 18), new Person("王五", 25) }; Arrays.sort(per); // 排序 for (int x = 0; x < per.length; x++) { System.out.println(per[x]); } } } Exception in thread"main"java.lang.ClassCastException: cn.mldn.demo.Person cannot be cast to java.lang.Comparable
现在发现此时需要让Person类实现Comparable接口,而这就是一个比较器。
二、Comparable接口
java.lang.Comparable接口是一个最为常用的比较器,那么此接口定义如下:
public interface Comparable {
public int compareTo(T o);
}
在Comparable接口之中发现只有一个compareTo()方法,而此方法可以返回三种类型的数据:-1(小)、0(等)、1(大)。
在之前学习String类的时候也学习过compareTo()方法,当时的方法是可以进行大小判断的。
范例:使用比较器
import java.util.Arrays; class Person implements Comparable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } @Override public int compareTo(Person o) { if (this.age > o.age) { return 1; } else if (this.age < o.age) { return -1; } return 0; } } public class TestDemo { public static void main(String[] args) throws Exception { Person per[] = new Person[] { new Person("张三", 20), new Person("李四", 18), new Person("王五", 25) }; Arrays.sort(per); // 排序 for (int x = 0; x < per.length; x++) { System.out.println(per[x]); } } }
以后只要是一组对象的大小比较一定使用Comparable接口。
三、二叉树实现:Binary Tree
既然已经知道了对象之间的大小比较操作,那么就可以利用此概念实现二叉树开发,二叉树的基本原则如下:
- 一个节点下可以保存两个节点,分别称为左子树和右子树;
- 取第一个数据作为根节点,比根节点小的数据要放在左子树上,比根节点大的数据要放在右子树上;
- 在进行输出的时候按照中序遍历(左-中-右)进行数据的取出。
范例:下面将利用Comparable实现二叉树操作
- 大小关系利用Comparable接口的compareTo()方法实现。
class Person implements Comparable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } @Override public int compareTo(Person o) { if (this.age > o.age) { return 1; } else if (this.age < o.age) { return -1; } return 0; } } @SuppressWarnings("rawtypes") class BinaryTree { private class Node { // 一定要存在节点类 private Comparable data; // 必须排序的是Comparable接口对象 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 toArrayNode() { if (this.left != null) { // 有左子树 this.left.toArrayNode(); } BinaryTree.this.retData[BinaryTree.this.foot++] = this.data; if (this.right != null) { this.right.toArrayNode(); } } } // ====================================== private Node root; // 根节点 private int count; // 统计对象的保存个数 private int foot; // 操作脚标 private Object[] retData; public void add(Comparable data) { if (data == null) { return; } Node newNode = new Node(data); // 将新的数据变为一个节点 if (this.root == null) { // 根节点没有数据 this.root = newNode; // 新的节点将作为根节点存在 } else { // 要保存在合适的节点中 this.root.addNode(newNode); } this.count++; // 保存个数加一 } public Object[] toArray() { if (this.root == null) { return null; } this.foot = 0; this.retData = new Object[this.count]; // 以保存大小开辟数组 this.root.toArrayNode(); return this.retData; } } public class BinaryTreeDemo { public static void main(String[] args) { BinaryTree bt = new BinaryTree(); bt.add(new Person("张三", 20)); bt.add(new Person("李四", 18)); bt.add(new Person("王五", 25)); Object[] data = bt.toArray(); for (int x = 0; x < data.length; x++) { System.out.println(data[x]); } } }
四、挽救的比较器:Comparator接口
在工作之中如果使用到比较器,肯定首选的是Comparable,但是Comparable有一个特点,它必须在一个类定义的时候就实现好接口,可是如果有这样一种情况,一个类已经开发完成了,并且此类不允许再做出任何修改,此类在先期设计的时候没有考虑对象数组的排序问题,后期又提出了此问题。但是代码已经不能变更,那么这个时候如何排序呢?
范例:开发好的类class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } public String getName() { return name; } public int getAge() { return age; } }
Person类已经开发完成,并且打包后交给客户使用了,但是后来需要进行对象数组排序,那么这个时候由于Person类无法修改了,那么只能够采用另外一种比较器:java.util.Comparator接口,此接口定义如下。
public interface Comparator {
public int compare(T o1, T o2);
public boolean equals(Object obj);
}
范例:定义专门的比较规则
class PersonComparator implements Comparator { @Override public int compare(Person o1, Person o2) { if (o1.getAge() > o2.getAge()) { return -1; } else if (o1.getAge() < o2.getAge()) { return 1; } return 0; } }
此类只能够为Person类服务。随后如果要排序的时候在Arrays类有如下一个方法:
- 排序:public static void sort(T[] a, Comparator)