首先是Student类,自然排序,实现Comparable接口
class Student implements Comparable {
String name;
int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
/*
* 向set集合中添加对象时,首先调用此对象所在类的hashCode方法,此对象的哈希值决定了此对象的存储位置,如果哈希值一样,
* 它要验证equals,此时equals方法返回true两个对象是同一个对象不能重复添加,如果哈希值不一样,不会验证equals 直接存储
* set集合存储(自定义类型)元素,一定要重写equals方法和hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//重写compareTo方法
@Override
public int compareTo(Object o) {
// 如果是Student类型的则调用里面的age属性,进行强转,按年龄从大到小的顺序排
if (o instanceof Student)
return this.age - ((Student) o).age;
return 0;
}
}
然后是Employee类,定制排序,不需要实现Comparable接口
class Employee {
String name;
int age;
public Employee() {
super();
}
public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}
/*
* 向set集合中添加对象时,首先调用此对象所在类的hashCode方法,此对象的哈希值决定了此对象的存储位置,如果哈希值一样,
* 它要验证equals,此时equals方法返回true两个对象是同一个对象不能重复添加,如果哈希值不一样,不会验证equals 直接存储
* set集合存储(自定义类型)元素,一定要重写equals方法和hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
}
最后使用Junit来测试
package com.yzy.treeset;
import java.util.Comparator;
import java.util.TreeSet;
import org.junit.Test;
/**
* @className TestTreeSet.java
* @author yangsir
* @version V1.0
* @date 2019年8月7日-下午8:03:21
* @description
*这里我使用了Junit来测试,没有使用泛型
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class TestTreeSet {
@Test // 测试自然排序,按年龄从小到大排
public void test1() {
// 直接new TreeSet对象向里面添加值
TreeSet tree = new TreeSet();
tree.add(new Student("a", 20));
tree.add(new Student("aaaa", 22));
tree.add(new Student("aaa", 24));
tree.add(new Student("aa", 21));
System.out.println(tree);// 直接输出
System.out.println("=================================================");
}
@Test // 测试定制排序,按对象姓名实现从小到大
public void test2() {
// new一个Comparator对象,使用匿名类写法,里面实现接口的重写
Comparator com = new Comparator() {
// 重写
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Employee && o2 instanceof Employee) {// 判断是否为Employee类型
Employee e1 = (Employee) o1;
Employee e2 = (Employee) o2;
return e1.name.compareTo(e2.name); // compareTo为正数时,姓名从小到大
}
return 0;
}
};
TreeSet tree = new TreeSet(com);
tree.add(new Employee("a", 20));
tree.add(new Employee("aaaa", 20));
tree.add(new Employee("aaa", 24));
tree.add(new Employee("aa", 21));
System.out.println(tree);
System.out.println("======================================");
}
@Test /// 按年龄 从小到大排,年龄相等 按姓名从大到小排
public void test3() {
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Employee && o2 instanceof Employee) {
Employee e1 = (Employee) o1;
Employee e2 = (Employee) o2;
if (e1.age - e2.age != 0)
return e1.age - e2.age;// 结果大于0,年龄从小到大排
else
return -e1.name.compareTo(e2.name); // 加了负号,所以姓名从大到小
}
return 0;
}
};
TreeSet tree = new TreeSet(com);
tree.add(new Employee("a", 20));
tree.add(new Employee("aaaa", 20));
tree.add(new Employee("aaa", 24));
tree.add(new Employee("aa", 21));
System.out.println(tree);
System.out.println("======================================");
}
@Test // 使用new TreeSet来实现test3
public void test4() {
// 这里要new Comparator(),写成匿名即可,其他同上
TreeSet tree = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Employee && o2 instanceof Employee) {
Employee e1 = (Employee) o1;
Employee e2 = (Employee) o2;
if (e1.age - e2.age != 0)
return e1.age - e2.age;
else
return e1.name.compareTo(e2.name);
}
return 0;
}
});
tree.add(new Employee("a", 20));
tree.add(new Employee("aaaa", 20));
tree.add(new Employee("aaa", 24));
tree.add(new Employee("aa", 21));
System.out.println(tree);
}
}
最后总结一下TreeSet排序的特点:
a.(自然排序)实现Comparable接口compareTo 方法按照属性排序
b.(定制排序)实现Comparator接口compare 方法按照属性排序