Comparable 和 Comparator 都是用来实现集合中元素的比较、排序的。
只是 Comparable 是在集合内部定义的方法实现的排序,而Comparator 是在集合外部实现的排序,
所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。
Comparator位于包java.util下,而Comparable位于包 java.lang下
一.Comparable 是一个对象,本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口)
自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式。
二.Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。
用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
1.Comparable用法示例:
需求:
每一个学生都有对应的归属地。
学生Student,地址String
学生属性:姓名,年龄
注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。
1.描述学生。
2.定义map容器,将学生作为键,地址作为值。存入。
3.获取map集合中的元素。
A.(代码MapTest.java)
package com.zlc.collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
class Student6 implements Comparable
private String name;
private int age;
public Student6(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return “姓名:”+name+”–>年龄:”+age;
}
//复写hashCode()和equals()方法
public int hashCode() {
return name.hashCode()+age*34;
}
public boolean equals(Object obj) {
if(!(obj instanceof Student6)) {
throw new ClassCastException(“类型不匹配–>不是学生对象”);
}
Student6 s = (Student6) obj;
return this.name.equals(s.name) && this.age == s.age;
}
@Override
public int compareTo(Student6 o) {
int num = new Integer(this.age).compareTo(new Integer(o.age));
if(num == 0){
return this.name.compareTo(o.name);
}
return num;
}
}
public class MapTest {
public static void main(String[] args) {
HashMap
hm.put(new Student6(“xiaozhou”,21), “商丘”);
hm.put(new Student6(“xiaozhou”,21), “南阳”);//此键值与上面的相同,会将上面的value覆盖
hm.put(new Student6(“xiaowang”,22), “新乡”);
hm.put(new Student6(“xiaochen”,20), “郑州”);
hm.put(new Student6(“xiaoliu”,19), “开封”);
//第一种取出方式 keySet
Set
Iterator
while(it.hasNext()){
Student6 stu = it.next();//取得学生对象stu
String addr = hm.get(stu);//注:取出stu对应的地址addr,地址在HashMap里面,用hm取出
System.out.println(stu+” …居住地址:”+addr);//这里的stu就会自动调用 Student6中的toString()方法
}
System.out.println(“—————————“);
//第二种取出方式 entrySet
Set
Iterator
while(iter.hasNext()){
Map.Entry
Student6 stu = me.getKey();
String addr = me.getValue();
System.out.println(stu+” …居住地址:”+addr);//这里的stu就会自动调用 Student6中的toString()方法
}
}
}
2.Comparator用法(其中也用到了Comparable,顺便比较一下。) 需求一:(在不使用Comparator的情况下)对学生对象的年龄进行升序排序。因为数据是以键值对形式存在的。所以要使用可以排序的Map集合。TreeMap 需求二:(在使用Comparator的情况下)先对学生对象的姓名进行升序排序,再按年龄升序。 B.(代码MapTest2.java)
package com.zlc.collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
class Student7 implements Comparable
private String name;
private int age;
public Student7(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Object)){
// return false;
throw new ClassCastException(“类型不匹配,不是学生对象”);
}
Student7 stu = (Student7) obj;
return this.name.equals(stu.name) && this.age == stu.age;
}
@Override
public int hashCode() {
// return super.hashCode();
return name.hashCode()+age*17;
}
@Override
public String toString() {
return “name: “+name+”–>age: “+age;
}
@Override//重写比较方法
public int compareTo(Student7 s) {
int num = new Integer(this.age).compareTo(new Integer(s.age));//按年龄从小到大进行排序
if(num == 0){//如果年龄相同,再比较姓名,(姓名按Unicode编码升序排序)
return this.name.compareTo(s.name);
}
return num;
}
}
class StuNameComparator implements Comparator
@Override
public int compare(Student7 s1, Student7 s2) {
int num = s1.getName().compareTo(s2.getName());//按姓名排序
if(num == 0){//如果名字相同,再比较年龄(如果年龄又相同,则不能加入到TreeMap集合中去)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
public class MapTest2 {
public static void main(String[] args) {
/*
* TreeMap(Comparator super K> comparator)
构造一个新的、空的树映射,该映射根据给定比较器进行排序。
* */
TreeMap
tm.put(new Student7(“zhangsan”,21), “北京”);
tm.put(new Student7(“lisi”,19), “上海”);
tm.put(new Student7(“wangwu”,24), “深圳”);
tm.put(new Student7(“wangwu”,18), “开封”);
tm.put(new Student7(“xiaohuan”,22), “商丘”);
tm.put(new Student7(“xiaocheng”,22), “新乡”);
tm.put(new Student7(“xiaocheng”,22), “郑州”);//如果该映射以前包含此键的映射关系,那么将替换旧值。
tm.put(new Student7(“xiaohuan”,22), “商丘”);
Set
Iterator
while(it.hasNext()){
Map.Entry
Student7 st = me.getKey();
String addr = tm.get(st);//通过对应的st获得对应的地址
System.out.println(st+” …居住地址:”+addr);
}
}
}
说明: 在排序时,如果不是调用sort方法,相要直接比较两个对象的大小,如下:
Comparator定义了俩个方法,分别是 int compare(T o1, T o2)和 boolean equals(Object obj),
用于比较两个Comparator是否相等
true only if the specified object is also a comparator and it imposes the same ordering as this comparator.
有时在实现Comparator接口时,并没有实现equals方法,可程序并没有报错,原因是实现该接口的类也是Object类的子类,而Object类已经实现了equals方法
Comparable接口只提供了 int compareTo(T o)方法,也就是说假如我定义了一个Person类,这个类实现了 Comparable接口,那么当我实例化Person类的person1后,我想比较person1和一个现有的Person对象person2的大小时,我就可以这样来调用:person1.comparTo(person2),通过返回值就可以判断了;而此时如果你定义了一个 PersonComparator(实现了Comparator接口)的话,那你就可以这样:PersonComparator comparator= new PersonComparator();
comparator.compare(person1,person2);。
分类目录
- arch/management (17)
- computer (38)
- java/j2ee (304)
- lnmpa (237)
- mac/iphone/ipad/android (11)
- mysql/oracle/postgresql (126)
- os/software (74)
- other (518)
- python (6)
- redis/memcached/mongo (31)
- sitebuild (143)
随便看看
标签云
程序员 创业 人生箴言 eclipse 快捷键 术语 索引 unix命令 vim wordpress java学习笔记 环境变量 oracle内置函数 index 人生 数据类型 nohup tuxedo mysql学习笔记 MS-DOS命令 servlet spring 职场进阶 职业进阶 服务器选购 服务器选型 apache JPA MongoDB 注解 tomcat 子女教育 jquery maven JVM aix命令 网络营销 java异常 seo 人生规划 关键字 css 网络推广 struts 系统优化 成长 frame iframe bluehost jdbc select 我的信仰 oracle函数 cookie HashMap 站长工具 乱码 ArrayList secureCRT jsp session tail find halt 事务 oracle单记录函数 算法 URL window table javascript操作表单元素 String 字符串处理 健康 http 域名 情感 more google A记录 域名解析 netstat 弹出对话框 弹出窗口 框架集 框架 excel 字符串 javascript函数 showModalDialog nginx number 数组 sql frameset 开源程序 java数组 软件 oracle服务友情链接
收藏链接