1. Map的主要实现类的区别
一、框架
/* java.util.Map:存储一对一对的数据 (key-value) ----> 高中学的"函数" y = f(x) y = 2 * x + 1 (x1,y1),(x2,y2)
* |---- HashMap:Map的主要实现类;线程不安全、效率高;可以存储null的key和value;底层使用Entry[](或Node[])
* |---- LinkedHashMap:HashMap的子类,可以实现按照添加的顺序实现遍历操作。对于频繁的遍历,建议使用此类。此类实际上是在HashMap结构的基础上,给每一个Node元素添加了一对指针,指向其前一个和后一个元素。
* |---- TreeMap:可以按照添加的元素node的key的指定的属性的大小顺序实现遍历操作。使用红黑树实现的数据存储。
* |---- Hashtable: Map的古老实现类;线程安全,效率低;不可以存储null的key或value;底层使用Entry[](或Node[])
* |---- Properties:是Hashtable的子类,主要用来处理属性文件的。其key和value都是String类型。
*/
public class MapTest {
@Test
public void test1(){
HashMap map = new HashMap();
map.put("Tom",67);
map.put(56,"AA");
map.put(null,"AA");
map.put(67,null);
map.put("Tim",78);
System.out.println(map);
}
@Test
public void test2(){
Hashtable map = new Hashtable();
// map.put(null,123);
// map.put("AA",null);
}
@Test
public void test3(){
HashMap map = new LinkedHashMap();
map.put("Tom",67);
map.put(56,"AA");
map.put(null,"AA");
map.put(67,null);
map.put("Tim",78);
System.out.println(map);
}
}
- TreeMap的测试(不带泛型)
import org.junit.Test;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapTest {
@Test
public void test1(){
TreeMap map = new TreeMap();
map.put("Tom",67);
map.put("Jerry",76);
map.put("Tonny",78);
map.put("Jack",99);
map.put("Jack",77);
map.put("Alice",66);
// map.put(87,66);
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
//向TreeMap中添加key和value。要求key考虑:① 自然排序 或 ② 定制排序
@Test
public void test2(){
TreeMap map = new TreeMap();
User u1 = new User("Tom",34);
User u2 = new User("Jerry",56);
User u3 = new User("Jack",44);
User u4 = new User("Alice",34);
User u5 = new User("Rose",12);
map.put(u1,89);
map.put(u2,55);
map.put(u3,34);
map.put(u4,78);
map.put(u5,88);
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
@Test
public void test3(){
TreeMap map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof User && o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
return u1.getAge() - u2.getAge();
}
throw new RuntimeException("输入的类型不匹配");
}
});
User u1 = new User("Tom",34);
User u2 = new User("Jerry",56);
User u3 = new User("Jack",44);
User u4 = new User("Alice",34);
User u5 = new User("Rose",12);
map.put(u1,89);
map.put(u2,55);
map.put(u3,34);
map.put(u4,78);
map.put(u5,88);
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
public class User implements Comparable{
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", 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 User(String name, int age) {
this.name = name;
this.age = age;
}
public User() {
}
@Override
public int compareTo(Object o) {
if(o instanceof User){
User u = (User)o;
int ageValue= this.age - u.age;
if(ageValue != 0){
return ageValue;
}
return this.name.compareTo(u.name);
}
throw new RuntimeException("输入的类型不匹配");
}
}
- Properties的使用
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class PropertiesTest {
@Test
public void test1() throws IOException {
Properties pros = new Properties();
FileInputStream fis = new FileInputStream(new File("info.properties"));
pros.load(fis);
String name = pros.getProperty("name");
String pwd = pros.getProperty("password");
System.out.println("name = " + name + ", pwd = " + pwd);
}
}
内容为:
name=tom
password=abc123
面试题:
HashMap与Hashtable的区别
2. HashMap的底层实现原理
三、
/* HashMap的底层源码分析:
* jdk7的实现:
* HashMap map = new HashMap(); //底层创建了一个长度为16的Entry[] table
* ....
* map.put(key1,value1);//添加一个key1-value1。 key1,value1封装为entry对象的两个属性,将entry对象放到数组table中。具体
* 应该放在table中的哪个位置呢?具体过程为:
*
* 1. 调用key1所属类的hashCode(),计算出key1的哈希值1,此哈希值1经过某个算法(hash())之后,得到哈希值2。此哈希值2就决定了key1-value1
* 封装为的entry1在数组table中的位置。假设此位置为索引i。
* 2. 如果table[i]位置上没有其他元素,则key1-value1封装的entry1直接添加成功。
* 如果table[i]位置上有其他元素,比如只有一对key2-value2封装的entry2。此时需要继续比较:
* 3. 比较key1和key2的哈希值,判断此哈希值是否相等:
* 3.1 两个哈希值不相等,则认为key1和key2就不相同。则key1-value1封装的entry1添加成功。此时entry1和entry2以链表方式存储。
* jdk7中将entry1放到table[i]中,通过单向链表指向entry2
* 3.2 两个哈希值相等,则需要继续调用key1所在类的equals()。
* 3.2.1 如果equals()返回true,则认为key1和key2相同,则默认情况下,value1替换旧的value2
* 3.2.2 如果equals()返回false,则认为key1和key2不相同。则key1-value1封装的entry1添加成功。此时entry1和entry2以链表方式存储。
* jdk7中将entry1放到table[i]中,通过单向链表指向entry2
*
*
* 在不断put添加的过程中,需要考虑扩容。默认扩容为原来的2倍。
* 什么时候扩容呢?默认情况下:数组的长度 * LOAD_FACTOR (默认值是0,75)
*
*
* jdk8相较于jdk7的区别:
* 1. HashMap map = new HashMap();//底层没有创建长度为16的数组。
* 2. 底层数组的类型调整为Node[],而非Entry[]
* 3. 在首次调用put()方法时,底层才开始创建长度为16的数组
* 4. jdk7中索引i位置如果有多个元素,构成的链表的特点与jdk8中的不同。
* “七上八下”
* 5. jdk8中如果数组索引i位置上的链表的长度大于8且数组的长度大于64时,此索引i位置上的元素都要调整为红黑树的数据结构进行存储。
*
* 说明:
* 1. 要求向HashMap中添加的key-value中key所在的类一定要重写:equals()\hashCode()
*
* 四、LinkedHashMap在HashMap的基础上,针对于Node增加了一对指针。证明:
* 在LinkedHashMap中定义了Entry结构如下:
* static class Entry<K,V> extends HashMap.Node<K,V> {
* Entry<K,V> before, after;
* Entry(int hash, K key, V value, Node<K,V> next) {
* super(hash, key, value, next);
* }
* }
*/
3. Collections工具类的使用
import org.junit.Test;
import java.lang.reflect.Array;
import java.util.*;
/**
* Collections:操作集合(List\Set\Map)的工具类
*
*
* Collection 和 Collections 区别?
*
*/
public class CollectionsTest {
/*
reverse(List):反转 List 中元素的顺序
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序 类似于:Arrays.sort(Object[])
sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序 类似于:
Arrays.sort(Object[],Comparator)
swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
*/
@Test
public void test1(){
List list = new ArrayList();
list.add(34);
list.add("AA");
list.add("AA");
list.add("AA");
list.add("CC");
list.add(new Date());
System.out.println(list);
// Collections.reverse(list);
// Collections.shuffle(list);
Collections.swap(list,0,2);
System.out.println(Collections.frequency(list, "AA"));
// System.out.println(list);
}
@Test
public void test2(){
//void copy(List dest,List src):将src中的内容复制到dest中
List list = new ArrayList();
list.add(34);
list.add("AA");
list.add("AA");
list.add("AA");
list.add("CC");
//错误的做法:
// List dest = new ArrayList();
// Collections.copy(dest,list);
// System.out.println(dest);
//正确的做法:
List dest = Arrays.asList(new Object[list.size()]);
Collections.copy(dest,list);
System.out.println(dest);
}
}
4. 泛型的理解
5. 泛型在集合中的使用
public class GenericTest {
//1.在集合中使用泛型之前的例子
@Test
public void test1(){
List list = new ArrayList();
list.add(68);
list.add(54);
list.add(88);
list.add(99);
//问题一:添加数据时,没有类型的校验,导致数据添加不安全。
// list.add("AA");
Iterator iterator = list.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
//问题二:可能导致类型转换异常。
int score = (int) obj;
System.out.println(score);
}
}
//2. 在集合中使用泛型的例子
//说明1:泛型参数赋的实参只能是引用数据类型。
//说明2:在实例化集合类时,指名了泛型的参数类型(比如:Integer)。则集合类内部的属性、方法、构造器中凡是使用类的泛型的位置
// 都替换为具体的泛型的参数类型(比如:Integer)。
//说明3:在使用泛型类或泛型接口时,没有指明类或接口的泛型参数,则默认将此类型理解为Object类型。
@Test
public void test2(){
// List<int> list = new ArrayList<int>();//报错
ArrayList<Integer> list = new ArrayList<>();//类型推断
list.add(67);
list.add(65);
list.add(78);
//编译不通过
// list.add("AA");
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
//不会出现类型转换异常
int score = iterator.next();
System.out.println(score);
}
}
@Test
public void test3(){
// Map<String,Integer> map = new HashMap<String,Integer>();
Map<String,Integer> map = new HashMap<>();
map.put("Tom",67);
map.put("Jack",77);
map.put("Rose",89);
// map.put(45,"Jerry");//编译不通过
//keySet():
Set<String> keySet = map.keySet();
Iterator<String> iterator = keySet.iterator();
while(iterator.hasNext()){
String key = iterator.next();
System.out.println(key);
}
//values():
Collection<Integer> values = map.values();
//entrySet():
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator1 = entrySet.iterator();
while(iterator1.hasNext()){
Map.Entry<String,Integer> entry = iterator1.next();
System.out.println(entry.getKey() + "--->" + entry.getValue());
}
}
}
- 练习:涉及到在Comparable 和 Comparator 中使用泛型
import org.junit.Test;
import java.util.*;
public class TreeMapTest {
//向TreeMap中添加key和value。要求key考虑:① 自然排序 或 ② 定制排序
@Test
public void test2() {
TreeMap<User, Integer> map = new TreeMap<User, Integer>();
User u1 = new User("Tom", 34);
User u2 = new User("Jerry", 56);
User u3 = new User("Jack", 44);
User u4 = new User("Alice", 34);
User u5 = new User("Rose", 12);
map.put(u1, 89);
map.put(u2, 55);
map.put(u3, 34);
map.put(u4, 78);
map.put(u5, 88);
Set<Map.Entry<User, Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<User, Integer>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
@Test
public void test3() {
TreeMap<User, Integer> map = new TreeMap<>(new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
return u1.getAge() - u2.getAge();
}
});
User u1 = new User("Tom", 34);
User u2 = new User("Jerry", 56);
User u3 = new User("Jack", 44);
User u4 = new User("Alice", 34);
User u5 = new User("Rose", 12);
map.put(u1, 89);
map.put(u2, 55);
map.put(u3, 34);
map.put(u4, 78);
map.put(u5, 88);
Set<Map.Entry<User, Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<User, Integer>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
public class User implements Comparable<User> {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", 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 User(String name, int age) {
this.name = name;
this.age = age;
}
public User() {
}
@Override
public int compareTo(User u) {
int ageValue = this.age - u.age;
if (ageValue != 0) {
return ageValue;
}
return this.name.compareTo(u.name);
}
}
6. 自定义泛型类、泛型接口、泛型方法
- 自定义泛型类、泛型方法
import java.util.ArrayList;
/**
* 自定义的泛型类
*
*/
public class Order<T> {
String orderName;
int orderId;
T orderT; //在属性中可以使用类的泛型参数
//在方法中使用类的泛型参数
public void setT(T t){
this.orderT = t;
}
public T getT(){
return orderT;
}
public void show(T t){
System.out.println(t);
}
//构造中使用类的泛型参数
public Order(String orderName, int orderId, T orderT) {
this.orderName = orderName;
this.orderId = orderId;
this.orderT = orderT;
}
public Order(T t){
this.orderT = t;
}
public Order(){}
//定义一个泛型方法
//将数组中的数据复制到ArrayList中,并返回
public static<E> ArrayList<E> copyFromArrayToList(E[] arr){
ArrayList<E> list = new ArrayList<E>();
for(int i = 0;i < arr.length;i++){
list.add(arr[i]);
}
return list;
}
}
public class SubOrder<T> extends Order<T> {
//功能的扩展
public T info(T t){
return null;
}
}
public class SubOrder1 extends Order<String> { //SubOrder1不是泛型类
// public static<E> ArrayList<E> copyFromArrayToList(E[] arr){
// ArrayList<E> list = new ArrayList<E>();
// for(int i = 0;i < arr.length;i++){
// list.add(arr[i]);
// }
// return list;
// }
}
- 测试上述代码
import org.junit.Test;
import java.util.ArrayList;
/**
* 自定义泛型类、泛型接口、泛型方法的使用
*
* 1. 在使用泛型类或泛型接口时,没有指明类或接口的泛型参数,则默认将此类型理解为Object类型。
* 2. 在实例化泛型类时,指名了泛型的参数类型(比如:Integer)。则泛型类内部的属性、方法、构造器中凡是使用类的泛型的位置
* 都替换为具体的泛型的参数类型(比如:Integer)。
*
* 3. 类的泛型参数在类实例化时,或子类继承泛型类时,指明类的泛型参数类型。
*
* 4. 泛型方法中的泛型参数是在方法调用时指名的。
*
* 5. 泛型类中,使用类的泛型的方法不能声明为static的。
* 泛型方法,可以根据需要,声明为static的。
*
*/
public class GenericTest1 {
@Test
public void test1(){
Order order = new Order();
order.show("TTT");
Order<Integer> order1 = new Order<>();
order1.show(123);
// order1.setT("Abc");
}
@Test
public void test2(){
SubOrder<String> sub = new SubOrder<>();
sub.show("AA");
SubOrder1 sub1 = new SubOrder1();
sub.show("AA");
}
//泛型方法使用的举例
@Test
public void test3(){
Order<Integer> order1 = new Order<>();
String[] arr = new String[]{"AA","BB","CC","DD"};
ArrayList<String> list = order1.copyFromArrayToList(arr);
System.out.println(list);
}
}
- 泛型类、泛型方法的使用举例
import java.util.List;
/**
* DAO: data(base) access object
*
*/
public class DAO<T> {
//增
public void add(T t){
}
//删
public T delete(int id){
return null;
}
//改
public void update(int id,T data){
}
//查
public T getInstance(int id){
return null;
}
public List<T> getForList(){
return null;
}
//泛型方法
//比如:获取表中的条目数、表中字段的最大值、最小值(最大的生日)等
public <E> E getValue(){
return null;
}
}
import java.sql.Date;
public class Customer {
int id;
String name;
String email;
Date birth;
}
public class CustomerDAO extends DAO<Customer> {
}
7. 泛型在继承上的体现
/*
泛型在继承上的体现
情况1:A类是B类的父类,结论:G<A> 和 G<B> 不是子父类的关系,是并列关系的两个类
情况2:A类是B类的父类,结论:A<G>是B<G>的父类,可以使用多态。
*/
@Test
public void test1(){
Object obj;
String str = new String();
obj = str;//多态
Object[] arr1;
String[] arr2 = new String[10];
arr1 = arr2;//动态
List<Person> list1;
List<Student> list2 = new ArrayList<Student>();
// list1 = list2; //编译不通过
List<Object> list3;
List<String> list4 = new ArrayList<String>();
// list3 = list4;//编译不通过
/*
反证法:
* 如果可以list3 = list4;
* list3 = new ArrayList<String>();
* list3.add(123);
* */
// String str1 = new Date(23423432L);
}
@Test
public void test2(){
List<String> list1;
ArrayList<String> list2 = new ArrayList<>();
list1 = list2;
}
8. 通配符的使用
/*
* 通配符的使用: ?
*
* A<?> 可以看做是A<G> 的父类。
* */
@Test
public void test3(){
ArrayList<String> list = new ArrayList<>();
// method(list); //List<Object> list1 = list
method1(list); //编译通过
method2(list);
ArrayList<Object> list1 = new ArrayList<>();
method2(list1);
}
public void method(ArrayList<Object> list1){
}
public void method1(ArrayList<String> list1){
}
public void method2(ArrayList<?> list1){
}
作业题1:
定义个泛型类 DAO<T>,在其中定义一个Map 成员变量,Map 的键为 String 类型,值为 T 类型。
分别创建以下方法:
public void save(String id,T entity): 保存 T 类型的对象到 Map 成员变量中
public T get(String id):从 map 中获取 id 对应的对象
public void update(String id,T entity):替换 map 中key为id的内容,改为 entity 对象
public List<T> list():返回 map 中存放的所有 T 对象
public void delete(String id):删除指定 id 对象
定义一个 User 类:
该类包含:private成员变量(int类型) id,age;(String 类型)name。
定义一个测试类:
创建 DAO 类的对象, 分别调用其 save、get、update、list、delete 方法来操作 User 对象,
使用 Junit 单元测试类进行测试。
public class User {
private int id;
private int age;
private String name;
public User() {
}
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != user.id) return false;
if (age != user.age) return false;
return name != null ? name.equals(user.name) : user.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + age;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
import sun.awt.SunHints;
import java.util.*;
public class DAO<T>{
private Map<String,T> map = new HashMap<>();
/*/*
* @Author
* @Description //TODO 保存 T 类型的对象到 Map 成员变量中
* @Date 19:57 2021/3/30
* @Param [id, entity]
* @return void
**/
public void save(String id,T entity){
map.put(id,entity);
}
/*/*
* @Author
* @Description //TODO 从 map 中获取 id 对应的对象
* @Date 19:58 2021/3/30
* @Param [id]
* @return T
**/
public T get(String id){
T entity = map.get(id);
return entity;
}
/*/*
* @Author
* @Description //TODO 替换 map 中key为id的内容,改为 entity 对象
* @Date 19:58 2021/3/30
* @Param [id, entity]
* @return void
**/
public void update(String id,T entity){
if (map.containsKey(id)){
map.put(id, entity);
}
}
/*/*
* @Author
* @Description //TODO 返回 map 中存放的所有 T 对象
* @Date 19:58 2021/3/30
* @Param []
* @return java.util.List<T>
**/
public List<T> list(){
//错误的
// return (List<T>)map.values();
//正确的
ArrayList<T> list = new ArrayList<>();
Collection<T> values = map.values();
for (T t : values){
list.add(t);
}
return list;
}
/*/*
* @Author
* @Description //TODO 删除指定 id 对象
* @Date 19:58 2021/3/30
* @Param [id]
* @return void
**/
public void delete(String id){
map.remove(id);
}
}
import org.junit.Test;
import java.util.List;
public class GenericTest {
@Test
public void test1(){
DAO<User> dao = new DAO<>();
dao.save("1001",new User(1001, 55, "张三"));
dao.save("1002",new User(1002, 45, "李四"));
dao.save("1003",new User(1003, 26, "王二麻子"));
dao.save("1004",new User(1004, 37, "慕容六"));
dao.save("1005",new User(1005, 62, "鬼脚七"));
dao.update("1003",new User(1003,42,"老八"));
System.out.println("*********************8");
System.out.println(dao.get("1005"));
System.out.println("*********************8");
dao.delete("1004");
List<User> list = dao.list();
// System.out.println(list);
list.forEach(System.out::println);
}
@Test
public void test(){
}
}
作业题2:
定义一个Employee类,
该类包含:private成员变量name,age,birthday,其中 birthday 为 MyDate 类的对象;
并为每一个属性定义 getter, setter 方法;
并重写 toString 方法输出 name, age, birthday
MyDate类包含:
private成员变量month,day,year;并为每一个属性定义 getter, setter 方法;
创建该类的 5 个对象,并把这些对象放入 TreeSet 集合中(TreeSet 需使用泛型来定义),
分别按以下两种方式对集合中的元素进行排序,并遍历输出:
1). 使Employee 继承 Comparable 接口,并按 name 排序
2). 创建 TreeSet 时传入 Comparator对象,按生日日期的先后排序。
package com.atguigu.exer2;
/**
* @author
* @create 2021-03-29 15:50
*/
public class Employee implements Comparable<Employee>{
private String name;
private int age;
private MyDate birthday;
public Employee(String name, int age, MyDate birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
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 MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}
@Override
public int compareTo(Employee o) {
return this.name.compareTo(o.name);
}
}
public class MyDate<Employee> {
private int year;
private int month;
private int day;
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
@Override
public String toString() {
return "MyBirthday{"+year +
"年," + month + "月,"+
day + "日"+
'}';
}
}
import java.util.*;
public class TreeSetTest {
public static void main(String[] args) {
Employee e1 = new Employee("Tom", 25, new MyDate(1996,2,15));
Employee e2 = new Employee("Alice", 26, new MyDate(1995,3,25));
Employee e3 = new Employee("AliceSem", 26, new MyDate(1995,3,21));
Employee e4 = new Employee("Rose", 27, new MyDate(1994,5,5));
Employee e5 = new Employee("Jack", 24, new MyDate(1997,7,23));
Employee e6 = new Employee("Zom", 23, new MyDate(1998,10,18));
Employee e7 = new Employee("Zomer", 23, new MyDate(1998,11,18));
// TreeSet<Employee> ts1 = new TreeSet<>();
// ts1.add(e1);
// ts1.add(e2);
// ts1.add(e3);
// ts1.add(e4);
// ts1.add(e5);
// //按name排序
// Iterator iterator1 = ts1.iterator();
// while (iterator1.hasNext()){
// System.out.println(iterator1.next());
// }
//按出生日期排序
Comparator<Employee> comparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
if (o1.getBirthday().getYear()!= o2.getBirthday().getYear()){
return o1.getBirthday().getYear()-o2.getBirthday().getYear();
}else if(o1.getBirthday().getMonth()!=o2.getBirthday().getMonth()){
return o1.getBirthday().getMonth() - o2.getBirthday().getMonth();
}else{
return o1.getBirthday().getDay() - o2.getBirthday().getDay();
}
}
};
TreeSet<Employee> ts = new TreeSet<>(comparator);
ts.add(e1);
ts.add(e2);
ts.add(e3);
ts.add(e4);
ts.add(e5);
ts.add(e6);
ts.add(e7);
Iterator iterator = ts.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}