我们先不谈TreeMap我们来直接聊聊HashMap,首先当我们用HashMap存储数据的时候,我们要如何将给出的数据排序呢?这是一个问题。
那么TreeMap本身是支持排序的,是对key进行的排序,但是需要用户定义。
实现排序:(主要有两种方法)
1、key的类型实现 java.lang.Comparable 接口 实现compareTo方法 根据返回的是正整数0负整数进行排序。
2、自己实现一个接口java.util.Comparator 实现里面的compare 方法根据返回的是正整数0负整数进行排序。
我们先看一下TreeMap的排序规则:
先在编译器书写如下代码:
TreeMap<String, Integer> treeMap = new TreeMap<String,Integer>();
treeMap.put("b", 1);
treeMap.put("g", 2);
treeMap.put("q", 3);
treeMap.put("a", 4);
treeMap.put("d", 5);
//而后我们再遍历一遍TreeMap
Set<String> setss = treeMap.keySet();
for(String key : setss) {
System.out.print(key + " ");
System.out.println(treeMap.get(key));
}
而后再看一下输出结果:
可以看到这里并没有按照12345的顺序排序,但是字母确排队很正确,这是因为TreeMap是按照key值排序,而没有按照value值排序。这里能够按照key值排序是因为String类里面实现了compareto方法
所以我们想让TreeMap排序只需要让Employee也实现这个方法
/**
* @author Hercules
* @version 创建时间:2020年1月13日 下午7:12:21
* 员工类
*/
public class Employee implements Comparable<Employee>{
private int eNo;
private String name;
private double salary;
public Employee() {
super();
}
public Employee(int eNo, String name, double salary) {
super();
this.eNo = eNo;
this.name = name;
this.salary = salary;
}
public int geteNo() {
return eNo;
}
public void seteNo(int eNo) {
this.eNo = eNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return String.format("Employee [eNo=" + eNo + ", name=" + name + ", salary=%6.2f]", salary);
}
@Override
public int compareTo(Employee o) {
return getSalary() > o.getSalary() ? 1 : getSalary()==o.getSalary() ? 0 : -1;
}
}
而后我们书写管理员工的类:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
public class EmployeeManager {
/**
* 存放所有员工的集合
*/
private Map<Employee,String> employees = new TreeMap<Employee,String>();
private static int no = 0;//自增的员工号
/**
* 添加员工
* @param employee
*/
public void addEmployee(Employee employee) {
no++;//每添加一次no就自增
employee.seteNo(no);
employees.put(employee,"");
}
/**
* 根据员工号查找员工
* @param no
* @return
*/
public Employee showEmployeeByENO(int no) {
Set<Employee> sets = employees.keySet();
Employee e = null;
for(Employee emp: sets) {
if(emp.geteNo() == no) {
e = emp;
break;
}
}
return e;
}
/**
* 显示所有员工信息
*/
public void showAllEmployee() {
//遍历map集合
Set<Employee> empls = employees.keySet();
for(Employee e : empls) {
System.out.println(e.toString());
}
}
/**
* 修改员工的薪水
* @param no
* @param salary
*/
public void updateEmployeeSalary(int no,double salary) {
Employee e = showEmployeeByENO(no);
if(e == null) {
System.out.println("查无此人,无法修改薪水");
return;
}
e.setSalary(salary);
}
/**
* 员工离职,移除系统
* @param no
*/
public void remove(int no) {
Employee e = showEmployeeByENO(no);
if(!employees.containsKey(e)) {
System.out.println("查无此人");
return;
}
employees.remove(e);
}
/**
* 查找工资最高的人
* @return
*/
public Employee getMaxSalary() {
Employee emp = null;
Set<Employee> empls = employees.keySet();
for(Employee e : empls) {
if(emp == null) {
emp = e;
}
if(emp.getSalary() < e.getSalary()) {
emp = e;
}
}
return emp;
}
/**
* 工资最低的人
* @return
*/
public Employee getMinSalary() {
// sort();
Employee emp = null;
Set<Employee> empls = employees.keySet();
for(Employee e : empls) {
if(emp == null) {
emp = e;
}
if(emp.getSalary() > e.getSalary()) {
emp = e;
}
}
return emp;
}
/**
* 平均工资
*/
public void avg() {
double total = 0;
Set<Employee> empls = employees.keySet();
for(Employee e : empls) {
total += e.getSalary();
}
System.out.println("平均工资为:"+(total/employees.size()));
}
}
可以看到这个类里面并没有排序方法。但是如果我们来写一个测试类呢?
import java.util.Set;
import java.util.TreeMap;
/**
* @author Hercules
* @version 创建时间:2020年1月13日 下午7:21:45
* 测试类
*/
public class Test {
public static void main(String[] args) {
EmployeeManager employeeManager = new EmployeeManager();
for(int i = 0;i < 10;i++) {
Employee e = new Employee(0, "张三"+i, Math.random()*10000);
employeeManager.addEmployee(e);
}
employeeManager.showAllEmployee();
}
}
来看一下所有员工的展示结果
可以看到这里所有的员工是按照工资从低到高的顺序在排序可是为什么他们没有按照别的属性排序呢,这里TreeMap的key是Employee类型的,这里面可不仅有工资一个属性,这就归功于我们重写的compareTo方法了,
public int compareTo(Employee o) {
return getSalary() > o.getSalary() ? 1 : getSalary()==o.getSalary() ? 0 : -1;
}
可以看到这里比较的是工资的值,来返回相应的值,所以在TreeMap中也是如此。
那么如果我们自己实现一个接口java.util.Comparator 实现里面的compare 方法根据返回的是正整数0负整数进行排序呢,这同样是可行的。
首先我们书写一个不重写那个方法的Employee2。
/**
* @author Hercules
* @version 创建时间:2020年1月14日 上午8:54:49
* 另一个不实现比较方法的员工类
*/
public class Employee2 {
private int eNo;
private String name;
private double salary;
public Employee2() {
super();
}
public Employee2(int eNo, String name, double salary) {
super();
this.eNo = eNo;
this.name = name;
this.salary = salary;
}
public int geteNo() {
return eNo;
}
public void seteNo(int eNo) {
this.eNo = eNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return String.format("Employee [eNo=" + eNo + ", name=" + name + ", salary=%6.2f]", salary);
}
}
实现一个接口java.util.Comparator 实现里面的compare 方法根据返回的是正整数0负整数进行排序
import java.util.Comparator;
/**
* @author Hercules
* @version 创建时间:2020年1月14日 下午4:52:52
* 类说明
*/
public class MyCompare implements Comparator<Employee2>{
@Override
public int compare(Employee2 o1, Employee2 o2) {
return o1.getSalary() > o2.getSalary() ? 1 : o1.getSalary()==o2.getSalary() ? 0 : -1;
}
}
而后我们再重写管理员工的那个类,这一次TreeMap要实现我们自己写的MyCompare那个类
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
public class EmployeeManager {
/**
* 存放所有员工的集合
*/
// private Map<Employee,String> employees = new TreeMap<Employee,String>();
//使用的时候传入比较对象
private Map<Employee2,String> employees = new TreeMap<Employee2,String>(new MyCompare());
private static int no = 0;//自增的员工号
/**
* 添加员工
* @param employee
*/
public void addEmployee(Employee2 employee) {
no++;//每添加一次no就自增
employee.seteNo(no);
employees.put(employee,"");
}
/**
* 根据员工号查找员工
* @param no
* @return
*/
public Employee2 showEmployeeByENO(int no) {
Set<Employee2> sets = employees.keySet();
Employee2 e = null;
for(Employee2 emp: sets) {
if(emp.geteNo() == no) {
e = emp;
break;
}
}
return e;
}
/**
* 显示所有员工信息
*/
public void showAllEmployee() {
//遍历map集合
Set<Employee2> empls = employees.keySet();
for(Employee2 e : empls) {
System.out.println(e.toString());
}
}
/**
* 修改员工的薪水
* @param no
* @param salary
*/
public void updateEmployeeSalary(int no,double salary) {
Employee2 e = showEmployeeByENO(no);
if(e == null) {
System.out.println("查无此人,无法修改薪水");
return;
}
e.setSalary(salary);
}
/**
* 员工离职,移除系统
* @param no
*/
public void remove(int no) {
Employee2 e = showEmployeeByENO(no);
if(!employees.containsKey(e)) {
System.out.println("查无此人");
return;
}
employees.remove(e);
}
/**
* 从高到低排序
*/
/*public void sort() {
for(int i = 0;i < employees.size()-1;i++) {//循环轮次
for(int j = 0 ; j < employees.size() - 1 - i ;j++) {//循环比较次数
if(employees.get(j).getSalary() < employees.get(j+1).getSalary()) {
//冒泡排序
Employee e = employees.get(j);
employees.set(j, employees.get(j+1));
employees.set(j+1, e);
}
}
}
}*/
/**
* 查找工资最高的人
* @return
*/
public Employee2 getMaxSalary() {
// sort();
Employee2 emp = null;
Set<Employee2> empls = employees.keySet();
for(Employee2 e : empls) {
if(emp == null) {
emp = e;
}
if(emp.getSalary() < e.getSalary()) {
emp = e;
}
}
return emp;
}
/**
* 工资最低的人
* @return
*/
public Employee2 getMinSalary() {
// sort();
Employee2 emp = null;
Set<Employee2> empls = employees.keySet();
for(Employee2 e : empls) {
if(emp == null) {
emp = e;
}
if(emp.getSalary() > e.getSalary()) {
emp = e;
}
}
return emp;
}
/**
* 平均工资
*/
public void avg() {
double total = 0;
Set<Employee2> empls = employees.keySet();
for(Employee2 e : empls) {
total += e.getSalary();
}
System.out.println("平均工资为:"+(total/employees.size()));
}
}
再书写测试类
/**
* @author Hercules
* @version 创建时间:2020年1月13日 下午7:21:45
* 类说明
*/
public class Test {
public static void main(String[] args) {
EmployeeManager employeeManager = new EmployeeManager();
for(int i = 0;i < 10;i++) {
Employee2 e = new Employee2(0, "张三"+i, Math.random()*10000);
employeeManager.addEmployee(e);
}
employeeManager.showAllEmployee();
}
}
得出如下结果: