1.List集合中存在自定义对象
现在集合容器中存数据的时候,字符串 整型 等
但是也可以存对象,集合中带有泛型 是一个类
package com.qf.b_list;
import java.util.ArrayList;
import java.util.List;
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
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//重写的toString方法 Object类
//将内存地址 转为一个字符串表示的形式 可以看到打印的数据 不再是一个内存地址了
//而是一个字符串了
public String toString() {
return "[name:" + name + ", age:" + age + "]";
}
}
public class Demo1 {
public static void main(String[] args) {
List<Person> persons = new ArrayList<Person>();
Person person1 = new Person("狗蛋", 24);
Person person2 = new Person("张三", 14);
Person person3 = new Person("王五", 34);
persons.add(person1);
persons.add(person2);
persons.add(person3);
System.out.println(persons);
//以上在存数据
//可以取数据
// System.out.println(persons.get(0));//获取的是集合中第一个对象
// System.out.println(persons.get(1));
// System.out.println(persons.get(2));
//
// //想只把狗蛋取出来
// //先取出来第一个person对象
// System.out.println(persons.get(0).getName());
for (Person person : persons) {
System.out.println(person.getName() + ":" + person.getAge());
}
}
}
2.ArrayList源码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LtFLfmj4-1679924730320)(C:\Users\马康飞\AppData\Roaming\Typora\typora-user-images\image-20230324193611823.png)]
RandomAccess :这个接口可以让ArrayList拥有快速随机访问的能力
源码: for循环比迭代器速度更快的
package com.qf.c_arrayList;
import java.awt.List;
import java.util.ArrayList;
import java.util.ListIterator;
public class Demo1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 1000000; i++) {
list.add("a");
}
//更快点
long start = System.currentTimeMillis();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
long end = System.currentTimeMillis();//12018毫秒
System.out.println(end - start);
// ListIterator<String> listIterator = list.listIterator();
// while (listIterator.hasNext()) {
// System.out.println(listIterator.next());
// }//15075
}
}
/**
* Default initial capacity.
*/
// DEFAULT_CAPACITY 默认的容量= 10
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
//空的数组 Object[]
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
//m默认的构造方法中空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
//真正存储元素的数组Object[] elementData
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
//最大数组的容量
private int size;
集合默认的可以存10个
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
构造方法是干嘛的? new ArrayList();
elementData 数组 默认是10
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
new ArrayList(4);
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
new ArrayList(list1)
三个构造方法只使用默认的形式
数组里面存10个数据, 但是超过这个数据怎么办? 自动扩容
ArrayList底层是基于动态数组实现的,在什么时候触发扩容? 当调用add、方法的时候 有可能触发
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
//
ensureCapacityInternal(size + 1); // Increments modCount!!
//elementData = {"q", "w"}
//elementData[0] = "q"
//elementData[1] = "w"
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {//最小容量
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
//minCapacity 最小容量
// elementData.length 数组长度
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
//扩容方法
private void grow(int minCapacity) {
// overflow-conscious code
//扩容前的数组的长度 10
int oldCapacity = elementData.length;
//扩容后的数组的长度
//int newCapacity = 10 + 10 / 2====> 15
// int newCapacity = oldCapacity + oldCapacity / 2;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//复制 数组
//copyOf(elementData, newCapacity)
//elementData = {1,2,3,4,5,6,7,8,9,10};
// elementData = {1,2,3,4,5,6,7,8,9,10, 0,0,0,0,0}
elementData = Arrays.copyOf(elementData, newCapacity);
}
通过grow是扩容方法 每次扩容 1.5倍
4.LinkedList【开发不用】
List是LinkedList的父接口
底层是链表
package com.qf.d_linkedList;
import java.util.LinkedList;
public class Demo1 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("张三");
list.add("李四");
list.add("王五");
System.out.println(list);
list.addFirst("狗蛋");
System.out.println(list);
list.addLast("网二");
System.out.println(list);
}
}
5.ArrayList和LinkedList区别
1.ArrayList底层是数组,LinkedList底层是链表
2.ArrayList在随机取数据的时候效率高于LinkedList
3.ArrayList在删除 和插入 的时候效率低于LinkedList
4.ArrayList会自己扩容 需要预留一定空间的
5.LinkedList 是存储数据的节点的信息以及节点信息的内存的指针
6.Object类
Object是所有类的基类
public String toString()
返回对象的字符串表示形式。 一般来说, toString
方法返回一个“textually代表”这个对象的字符串。 结果应该是一个简明扼要的表达,容易让人阅读。 建议所有子类覆盖此方法。
package com.qf.a_object;
class Person {
String name;
int age;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Demo1 {
public static void main(String[] args) {
Object object = new Object();
Object object2 = new Object();
System.out.println(object);
// 该toString类方法Object返回一个由其中的对象是一个实例,
//该符号字符`的类的名称的字符串@ ”和对象的哈希码的无符号的十六进制表示。 换句话说,这个方法返回一个等于下列值的字符串:
//
// getClass().getName() + '@' + Integer.toHexString(hashCode())
System.out.println(object.toString());//java.lang.Object@15db9742
Person person = new Person();
System.out.println(person);
}
}
public boolean equals(Object obj)
指示一些其他对象是否等于此对象。判断两个对象是否相等
public boolean equals(Object obj) {
return (this == obj);
}
== : b比较的是内存地址
objec1.equals(object2)
为啥 String类下面equals如果内容一样的可以返回true? 当父类的需求满足不了子类的需求
String类重写了Object类的equals
需求: 比较两个对象的内容是否一样【重点】
package com.qf.a_object;
class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {//如果内存地址一样 就返回true
return true;
}
//如果内存地址不一样,但是内容一样咋写
//equals(Object obj) Object obj = student2;//向上转型
//student1.equals(student2)
//obj instanceof Student
if (obj instanceof Student) {// student2 instanceof Student true
Student stu = (Student)obj;//向下转型
//student2===>stu
// student1.name.equals(student2.name) true && student1.age == student2.age
return this.name.equals(stu.name) && this.age == stu.age;
}
return false;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
public class Demo3 {
public static void main(String[] args) {
Student student1 = new Student("土豆", 12);
Student student2 = new Student("土豆", 12);
System.out.println(student1.equals(student2));//因为Object类是Student的父类
//以上是false, 但是真实的开发的时候,关注的是内容 而不是地址
//只要内容一样也得给我true。 咋办?重写eqauls方法
}
}
Employee类 id name
创建两个对象 如果内容一样 使用equals返回的是一个true
package com.qf.a_object;
class Employee {
int id;
String name;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
//employee1.equals(employee2)
@Override
public boolean equals(Object obj) {//employee2 赋值 obj 这叫象上转型
//this ===>employee1
//obj =====>employee2
if (this == obj) {//比较内存地址
return true;
}
//如果内存地址不一样的话 接下来判断内容
if (obj instanceof Employee) {//为强转做准备
Employee emp = (Employee) obj;
return this.id == emp.id && this.name.equals(emp.name);
}
return false;
}
}
public class Demo4 {
public static void main(String[] args) {
Employee employee1 = new Employee(1, "老邢");
Employee employee2 = new Employee(1, "老邢");
System.out.println(employee1.equals(employee2));
}
}
public int hashCode()
返回对象的哈希码值。 支持这种方法是为了散列表,如HashMap
提供的那样 。
在Object类中,将十六进制的内存地址转为十进制的值,就叫hash值
如果内存地址不一样,那么哈希也是不一样的
hashCode
的总合同是:
如果根据equals(Object)
方法两个对象相等,则在两个对象中的每个对象上调用hashCode
方法必须产生相同的整数结果
package com.qf.a_object;
class Man {
int id;
String name;
public Man(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Man) {
Man man1 = (Man)obj;
return man1.id == this.id && man1.name.equals(this.name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
public class Demo6 {
public static void main(String[] args) {
//比较两个对象的而内容是否一致
Man man1 = new Man(2, "蔡徐坤");
Man man2 = new Man(2, "蔡徐坤");
System.out.println(man1.equals(man2));//true
//如果根据`equals(Object)`方法两个对象相等,
//则在两个对象中的每个对象上调用`hashCode`方法必须产生相同的整数结果
System.out.println(man1.hashCode());
System.out.println(man2.hashCode());
//只能重写hashCode方法 不要再使用Object类下面hashCode
}
}
请注意,无论何时覆盖equlas方法,通常需要覆盖hashCode方法,以便维护hashCode方法的通用合同,该方法规定相等的对象必须具有相等的哈希码
咱们在干嘛:比较两个对象的内容是否相等,和内存地址无关!!!
package com.qf.a_object;
class Man {
int id;
String name;
public Man(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
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;
Man other = (Man) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class Demo6 {
public static void main(String[] args) {
//比较两个对象的而内容是否一致
Man man1 = new Man(2, "蔡徐坤");
Man man2 = new Man(2, "蔡徐坤");
System.out.println(man1.equals(man2));//true
//如果根据`equals(Object)`方法两个对象相等,
//则在两个对象中的每个对象上调用`hashCode`方法必须产生相同的整数结果
System.out.println(man1.hashCode());
System.out.println(man2.hashCode());
//只能重写hashCode方法 不要再使用Object类下面hashCode
}
}
7.Set集合
Set集合也是用来存储数据的
Set集合父接口 Collection 接口
Set存储数据的时候的效果是 无序的 不可重复的
Set接口下面有两个 实现类:
HashSet : 底层是hash值进行存储的。如果hash值一样的就无法存到集合中
TreeSet: 底层是二叉 树,对存入的数据进行自然排序
7.1HashSet
学习方法
package com.qf.b_hashSet;
import java.util.HashSet;
import java.util.Set;
public class Demo1 {
public static void main(String[] args) {
Set<String> set= new HashSet<String>();
set.add("b");
set.add("c");
set.add("b");
set.add("a");
System.out.println(set);//[a, b, c]
Object[] arr = set.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
for (String string : set) {
System.out.println(string);
}
}
}
7.2set集合中自定义的对象
package com.qf.b_hashSet;
import java.util.HashSet;
import java.util.Set;
class Person {
int id;
String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
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;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class Demo2 {
public static void main(String[] args) {
Set<Person> set = new HashSet<Person>();
Person person1 = new Person(1, "老邢");
Person person2 = new Person(2, "骚磊");
Person person3 = new Person(1, "老邢");
set.add(person1);
set.add(person2);
set.add(person3);
System.out.println(set);
//现在存了三个对象。感觉可以吗?不可以 关注是内容!!!咋干掉?
//重写equlas和hashCode方法
}
}
总结: 如果将对象存入到hashSet中的时候,必须重写当前类的equals和hashCode方法 为了保证对象的内容不重复。
HashSet的底层是HashMap JDK1.8 数组 + 链表 + 红黑树 三个组成
7.3TreeSet
也是Set接口的实现类。可以保证数据唯一型。存储也是无序的。
同时对存入数据会进行自然排序
package com.qf.c_treeset;
import java.util.Set;
import java.util.TreeSet;
public class Demo1 {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
set.add(78);
set.add(65);
set.add(21);
set.add(70);
System.out.println(set);//[21, 65, 70, 78]
Set<String> set1 = new TreeSet<String>();
set1.add("b");
set1.add("ba");
set1.add("a");
set1.add("ab");
System.out.println(set1);//[a, ab, b, ba]
for (String string : set1) {
System.out.println(string);
}
}
}
7.4TreeSet存自定义的对象
存对象的时候需要在类的实现Comparable这个接口。该接口对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo
方法被称为其自然比较方法 。
int compareTo(T o)
将此对象与指定的对象进行比较以进行排序。
返回一个负整数,零或正整数,因为该对象小于,等于或大于指定对象。
person1.compareTo(person2)
如果返回值是负数, 就证明 person1小于 person2 排序 person1 排在person2前面
如果返回值是0,就证明相等,不存了
如果是个正数,就证明大于 person2 排在person1的前面
package com.qf.c_treeset;
import java.util.Set;
import java.util.TreeSet;
class Person implements Comparable<Person>{
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
//1. this 就是狗蛋 o也是狗蛋
//2. this 潘周丹 o狗蛋 【 潘周丹 狗蛋】
//3. this 旺财 o狗蛋 【潘周丹 狗蛋 旺财 】
//4.this erdsan o狗蛋 【潘周丹 狗蛋 旺财 】
int num = this.age - o.age;
return num;
//2.[潘周丹 狗蛋]
//3.[旺财 狗蛋]
//4.[潘周丹 旺财erdan 狗蛋]
}
}
public class Demo2 {
public static void main(String[] args) {
Set<Person> set = new TreeSet<Person>();
set.add(new Person("狗蛋", 24));//这行开始报错
set.add(new Person("潘周丹", 21));
set.add(new Person("旺财", 23));
set.add(new Person("erdsan", 24));
//Exception in thread "main" java.lang.ClassCastException:
//com.qf.c_treeset.Person cannot be cast to java.lang.Comparable
System.out.println(set);
//按照age进行排序
}
}
//按照年龄进行排序
package com.qf.c_treeset;
import java.util.Set;
import java.util.TreeSet;
//先按照年龄 如果年龄 再字符串比较
class Student implements Comparable<Student>{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Student o) {
int num = this.age - o.age;
if (num == 0) {//当 age 相等的时候
int num1 = this.name.compareTo(o.name);
return num1;
}
return num;
}
}
public class Demo3 {
public static void main(String[] args) {
Set<Student> set = new TreeSet<Student>();
set.add(new Student("b", 65));
set.add(new Student("d", 35));
set.add(new Student("c", 25));
set.add(new Student("a", 35));
set.add(new Student("浩正", 35));
System.out.println(set);
}
}
通过查阅API我们得知TreeSet集合是基于TreeMap的实现,而TreeMap是基于二叉树(红黑树)结构,也就是说TreeSet集合的底层使用的二叉树(红黑树)结构。
树结构:它也是数据结构中的一种。在计算机领域中树结构指的是倒立的树。
树结构存储的数据,每个数据也需要节点来保存。
而TreeSet集合底层是二叉树的数据结构,什么是二叉树呢?
二叉树:每个节点的下面最多只能有2个子节点。
说明:最多表示一个节点下面可以有两个子节点或者一个子节点或者没有子节点。
在二叉树的根节点左侧的节点称为左子树,在根节点的右侧的节点称为右子树。
既然已经得知TreeSet集合底层是二叉树,那么二叉树是怎样存储数据的呢?是怎样保证存储的数据唯一并有序的呢?
二叉树的存储流程:
当存储一个元素的时候,如果是树的第一个元素,这个元素就作为根节点。
如果不是第一个元素,那么就拿要存储的元素与根节点进行比较大小:
大于根元素:就将要存储的元素放到根节点的右侧,作为右叶子节点。
等于根元素:丢弃。
小于根元素:就将要存储的元素放到根节点的左侧,作为左叶子节点。
总结:二叉树是通过比较大小来保证元素唯一和排序的。
20 10 31 5 13 23 51
关于TreeSet在存储数据的时候,会有一个排序的问题u,。使用一个接口叫Comparable这个接口
咱们还可以使用另外一种方式进行排序。叫比较器的写法
TreeSet(Comparator<? super E> comparator)
构造一个新的,空的树集,根据指定的比较器进行排序。
package com.qf.c_treeset;
import java.util.Comparator;
import java.util.TreeSet;
class Emp {
String name;
int age;
public Emp(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + "]";
}
}
class MyComparator implements Comparator<Emp> {
@Override
public int compare(Emp o1, Emp o2) {
// TODO Auto-generated method stub
int num1 = o2.age - o1.age;
return num1;
}
}
public class Demo4 {
public static void main(String[] args) {
//借助于有参的构造方法
//TreeSet(Comparator<? super E> comparator)
//构造一个新的,空的树集,根据指定的比较器进行排序。
TreeSet<Emp> emps = new TreeSet<Emp>(new MyComparator());
emps.add(new Emp("狗蛋", 23));
emps.add(new Emp("狗蛋1", 22));
emps.add(new Emp("狗蛋2", 24));
emps.add(new Emp("狗蛋3", 21));
System.out.println(emps);
}
}
8.匿名内部类
目的为了减少代码量
8.1基于抽象类匿名内部类
package com.qf.d_niming;
abstract class Person {
public abstract void eat();
}
//class Man extends Person {
//
// @Override
// public void eat() {
// // TODO Auto-generated method stub
//
// }
//
//}
public class Demo1 {
public static void main(String[] args) {
// Person person = new Person() {
// @Override
// public void eat() {
// // TODO Auto-generated method stub
// System.out.println("吃饭");
// }
// };
// person.eat();
new Person() {
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("吃汉堡");
}
}.eat();
}
}
真实的开发咋用
一个方法的参数是一个抽象类
package com.qf.d_niming;
abstract class Student {
public abstract void sleep();
}
public class Demo2 {
public static void main(String[] args) {
//test方法参数是抽象类的对象
test(new Student() {
@Override
public void sleep() {
// TODO Auto-generated method stub
System.out.println("睡得老想了");
}
});
}
public static void test (Student stu) {
stu.sleep();
}
}
8.2基于接口的匿名内部类
package com.qf.d_niming;
interface Dog {
void lookHome();
}
public class Demo3 {
public static void main(String[] args) {
new Dog() {
@Override
public void lookHome() {
// TODO Auto-generated method stub
System.out.println("看家比较负责任");
}
}.lookHome();
}
}
package com.qf.c_treeset;
import java.util.Comparator;
import java.util.TreeSet;
class Emp {
String name;
int age;
public Emp(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + "]";
}
}
public class Demo4 {
public static void main(String[] args) {
//借助于有参的构造方法
//TreeSet(Comparator<? super E> comparator)
//构造一个新的,空的树集,根据指定的比较器进行排序。
TreeSet<Emp> emps = new TreeSet<Emp>(new Comparator<Emp>() {
@Override
public int compare(Emp o1, Emp o2) {
// TODO Auto-generated method stub
int num = o1.age - o2.age;
return num;
}
});
emps.add(new Emp("狗蛋", 23));
emps.add(new Emp("狗蛋1", 22));
emps.add(new Emp("狗蛋2", 24));
emps.add(new Emp("狗蛋3", 21));
System.out.println(emps);
}
}
mo3 {
public static void main(String[] args) {
new Dog() {
@Override
public void lookHome() {
// TODO Auto-generated method stub
System.out.println("看家比较负责任");
}
}.lookHome();
}
}
```java
package com.qf.c_treeset;
import java.util.Comparator;
import java.util.TreeSet;
class Emp {
String name;
int age;
public Emp(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + "]";
}
}
public class Demo4 {
public static void main(String[] args) {
//借助于有参的构造方法
//TreeSet(Comparator<? super E> comparator)
//构造一个新的,空的树集,根据指定的比较器进行排序。
TreeSet<Emp> emps = new TreeSet<Emp>(new Comparator<Emp>() {
@Override
public int compare(Emp o1, Emp o2) {
// TODO Auto-generated method stub
int num = o1.age - o2.age;
return num;
}
});
emps.add(new Emp("狗蛋", 23));
emps.add(new Emp("狗蛋1", 22));
emps.add(new Emp("狗蛋2", 24));
emps.add(new Emp("狗蛋3", 21));
System.out.println(emps);
}
}