(最近正好看这本书 电子版随后上传 文章转载)改善java的151个建议 71 Comparator和comparable接口
2018-03-20 14:09
597 查看
举个例子: 给公司职员排序,按照工号排序,先定义一个职员类编写Employee类实现Comparable接口
这是一个简单的javabean,描述的是一个员工的基本信息,其中id是员工编号,按照进入公司的先后顺序编码,position是岗位描述,表示是经理还是普通职员,这是一个枚举类型:
Employee类的compareTo()方法,是Comparable接口必须要实现的方法,使用apach的工具类来实现,表明是按照id的自然序列排序的(升序)。一切准备完毕,我们看看如何排序:
【运行结果】:
本着“领导为先”的理念,按职位从高到低排序,先是老板,然后是经理,最后是普通职员,Employee已经是一个稳定类,为了一个排序功能修改它,影响按照id排序,不是一个好办法。Collections.sort()方法有一个重载方法sort(List<T> list, Comparator<? super T> c),有一个Comparator接口参数,我们实现这个接口:
创建了一个职位排序法,按职位高低排序,测试一下:
为了照顾员工,需要按职位由低到高排序两个办法:Collections.reverse(List<?> list)方法实现倒序排列
Collections.sort(List<?> list,Collections.reverseOrder(new PositionComparator())也可以
用这两个方法来测试:
【运行结果】:
按照职位由地到高排序,结果正确 先按职位排序,职位 相同按id排序
在compareTo或compare方法中先判断职位是否相等,职位相等再根据工号排序修改Employee类的compareTo()方法为
Comparator接口是一个工具类接口,用作比较,与原类的逻辑没有关系;
package hello; import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; public class Employee implements Comparable<Employee>{ //id是根据进入公司的先后顺序编码的 private int id; //姓名 private String name; //职位 private Position position; public Employee(int id, String name, Position position) { super(); this.id = id; this.name = name; this.position = position; } //按照id号排序,也就是资历的深浅排序 @Override public int compareTo(Employee o) { // TODO Auto-generated method stub return new CompareToBuilder().append(id, o.id).toComparison(); } @Override public String toString(){ return ToStringBuilder.reflectionToString(this); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Position getPosition() { return position; } public void setPosition(Position position) { this.position = position; } }
这是一个简单的javabean,描述的是一个员工的基本信息,其中id是员工编号,按照进入公司的先后顺序编码,position是岗位描述,表示是经理还是普通职员,这是一个枚举类型:
public enum Position { Boss, Manager,staff }职位有三个级别: Boss(老板), Manager(经理), Staff(职员)按id排序
Employee类的compareTo()方法,是Comparable接口必须要实现的方法,使用apach的工具类来实现,表明是按照id的自然序列排序的(升序)。一切准备完毕,我们看看如何排序:
package hello; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class HelloWord { public static void main(String[] args) { List<Employee> list = new ArrayList<Employee>(5); // 一个老板 list.add(new Employee(1001, "张三", Position.Boss)); // 两个经理 list.add(new Employee(1006, "赵四", Position.Manager)); list.add(new Employee(1003, "王五", Position.Manager)); // 两个职员 list.add(new Employee(10002, "李六", Position.staff)); list.add(new Employee(1005, "马牛", Position.staff)); // 按照id排序,也就是按照资历深浅排序 Collections.sort(list); for (Employee e : list) { System.out.println(e); } } }
【运行结果】:
hello.Employee@46244bb9[id=1001,name=张三,position=Boss] hello.Employee@4b5d7792[id=1003,name=王五,position=Manager] hello.Employee@3e0a765c[id=1005,name=马牛,position=staff] hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager] hello.Employee@6909037d[id=10002,name=李六,position=staff]是按照id升序排列的,结果正确。按职位排序
本着“领导为先”的理念,按职位从高到低排序,先是老板,然后是经理,最后是普通职员,Employee已经是一个稳定类,为了一个排序功能修改它,影响按照id排序,不是一个好办法。Collections.sort()方法有一个重载方法sort(List<T> list, Comparator<? super T> c),有一个Comparator接口参数,我们实现这个接口:
//职位排序器 class PositionComparator implements Comparator<Employee>{ @Override public int compare(Employee o1, Employee o2) { //按照职位降序排列 return o1.getPosition().compareTo(o2.getPosition()); }
创建了一个职位排序法,按职位高低排序,测试一下:
Collections.sort(list, new PositionComparator()); for (Employee e : list) { System.out.println(e); }【运行结果】:
hello.Employee@46244bb9[id=1001,name=张三,position=Boss] hello.Employee@4b5d7792[id=1003,name=王五,position=Manager] hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager] hello.Employee@3e0a765c[id=1005,name=马牛,position=staff] hello.Employee@6909037d[id=10002,name=李六,position=staff]按照职位排序,结果正确。 按照职位从低到高排序
为了照顾员工,需要按职位由低到高排序两个办法:Collections.reverse(List<?> list)方法实现倒序排列
Collections.sort(List<?> list,Collections.reverseOrder(new PositionComparator())也可以
用这两个方法来测试:
Collections.reverse(list); for (Employee e : list) { System.out.println(e); } System.out.println("----"); Collections.sort(list, Collections.reverseOrder(new PositionComparator())); for (Employee e : list) { System.out.println(e); }
【运行结果】:
hello.Employee@6909037d[id=10002,name=李六,position=staff] hello.Employee@3e0a765c[id=1005,name=马牛,position=staff] hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager] hello.Employee@4b5d7792[id=1003,name=王五,position=Manager] hello.Employee@46244bb9[id=1001,name=张三,position=Boss] ---- hello.Employee@6909037d[id=10002,name=李六,position=staff] hello.Employee@3e0a765c[id=1005,name=马牛,position=staff] hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager] hello.Employee@4b5d7792[id=1003,name=王五,position=Manager] hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
按照职位由地到高排序,结果正确 先按职位排序,职位 相同按id排序
在compareTo或compare方法中先判断职位是否相等,职位相等再根据工号排序修改Employee类的compareTo()方法为
@Override public int compareTo(Employee o) { return new CompareToBuilder() .append(position, o.position) //按照职位排序 .append(o.id,id).toComparison(); //工号排序 }排序代码:
Collections.sort(list); for (Employee e : list) { System.out.println(e); }【运行结果】:
hello.Employee@4d871a69[id=1001,name=张三,position=Boss] hello.Employee@631803fb[id=1006,name=赵四,position=Manager] hello.Employee@4b5d7792[id=1003,name=王五,position=Manager] hello.Employee@655538e5[id=1005,name=马牛,position=staff] hello.Employee@20e0b1d6[id=1002,name=李六,position=staff]总结: 实现了Comparable接口类表明自身可比较,有了比较才能进行排序;
Comparator接口是一个工具类接口,用作比较,与原类的逻辑没有关系;
相关文章推荐
- [编写高质量代码:改善java程序的151个建议]后记
- 摘自<编写高质量代码:改善Java程序的151个建议>
- 编写高质量代码:改善Java程序的151个建议(第5章:数组和集合___建议79~82)
- 编写高质量代码:改善Java程序的151个建议(第3章:类、对象及方法___建议31~35)
- 改善java程序的151个建议--枚举和注解
- [编写高质量代码:改善java程序的151个建议]建议52 推荐使用String直接量赋值
- [编写高质量代码:改善java程序的151个建议]建议70 子列表只是原列表的一个视图
- [编写高质量代码:改善java程序的151个建议]建议91 枚举和注解结合使用威力更大
- 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议88~92)
- 改善java程序的151个建议 读后感三
- 编写高质量代码:改善Java程序的151个建议 --[36~51]
- 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议16~20)
- [编写高质量代码:改善java程序的151个建议]建议67 不同的列表选择不同的遍历方法
- [编写高质量代码:改善java程序的151个建议]摘记一(P1~P60)
- [编写高质量代码:改善java程序的151个建议]建议43 避免对象浅拷贝; 建议44:推荐使用序列化实现对象的深拷贝