比较器

一、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)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值