TreeSet :基于TreeMap 。可以使用元素的自然顺序对元素进行排序(元素对应的类实现Comparable 接口,重写compareTo 方法),或由Comparator集合创建时提供,这取决于所使用的构造方法。
构造函数:
TreeSet(Comparator super E> comparator) //构造一个新的,空的树集,根据指定的比较器进行排序。
**TreeSet 对元素排序有两种方法:
1.元素自身的自然排序方法,其实就是实现Comparable 接口 ,重写compareTo 方法。如果元素自身不具备自然排序,或者是具备的自然排序不是所需要的,这时只能用第二种方法。
2.比较器。其实就是在创建TreeSet 集合时,在构造函数中指定的比较方法
需要定义一个类,实现Comparator 接口,重写compare 方法**
Comparator 接口:(比较器)
强行对某个对象collection 进行整体排序的比较函数
方法:
int compare(T o1, T o2) 比较其两个参数的顺序。
boolean equals(Object obj) 指示某个其他对象是否等于此比较器。
比较器的使用
1.创建类实现Comparator 接口
package Collection;
import java.util.Comparator;
//创建类实现 Comparator 接口 实现compare 方法
public class Comparator_Beauty implements Comparator{
@Override
public int compare(Object o1, Object o2) {
//类型转换
Beauty b1 = (Beauty)o1;
Beauty b2 = (Beauty)o2;
//按照名字比较
int temp=b1.getName().compareTo(b2.getName());
return temp==0?b1.getAge()-b2.getAge():temp;
}
}
2.在创建集合对象时,向构造函数中传入比较器对象
//使用构造器比较//在创建集合对象时,传入构造器方法
Set set = new TreeSet(new Comparator_Beauty());
运行结果:
chenyu1 18
chenyu3 18
chenyu5 16//按照姓名排序
小结:
1.实现Comparator 接口时,为什么没有实现 equals 方法?因为类默认的是继承 Object 类的。所以equals 方法被覆盖。同时,TreeSet 可以通过 Compare 方法来保证元素的唯一性。那么为Comparator 中定义的equals 方法有什么用?这个equals 是用来比较 两个比较器对象是否一样的。
2.为什么TreeSet 的比较方法有这两种?在TreeSet 的底层代码中,定义了 比较器的对象引用,当引用不为null 时,调用 比较器方法 compare ;当比较器为空的时候,调用自然排序的方法 compareTo
TreeSet 的使用总结:
在往集合中存储对象时,通常对象都要覆盖 hashCode ,equals ,同时实现了Comaparable 接口,建立对象的自然排序,通常还要重写 toString() 【不复写,在获取集合元素//next()时,就会调用底层的 hashCode 方法,输出哈希值】
—————————————————比较器的练习———–——————————————
一:对字符串自然排序
package Collection;
import java.util.*;
//对字符串进行排序
public class ComparatorTest_Set {
public static void main(String[] args){
//创建集合
Set set = new TreeSet();
//1.按照字符串大小排序
set.add("ahs");
set.add("a");
set.add("zshd");
set.add("fnwh");
//获取元素
for(Iterator it = set.iterator();it.hasNext();){
System.out.println(it.next());
}
}
}
对代码内部的分析:
1.为什么可以实现排序? 字符串本身是有自己的compareTo 方法。(完成比较和保证唯一性)
2. 为什么可以实现输出串? 使用next() 方法返回的是,字符串对象。但是字符串自己有自己的toSteing() 方法。(不然输出的就是哈希值了)
二,按照长度对字符串排序
String 中的自然排序方法,无法完成所需,因此只能使用比较器
package Collection;
import java.util.Comparator;
//写字符串按照长度排序的构造器
public class ComparatorByLength_String implements Comparator{
@Override
public int compare(Object o1, Object o2) {
//类型转换
String s1= (String)o1;
String s2= (String)o2;
int temp= s1.length()-s2.length();//比较主要条件
return temp==0?s1.compareTo(s2):temp;//同时要比较次要条件
}
}
Set set = new TreeSet(new ComparatorByLength_String());
HashSet 的索引快,如果需求为:提高唯一性元素的查询效率,还想保证有序(怎么输入就怎么输出)
LinkedHashSet:是HashSet 的子类。
哈希表和链表实现了Set接口,具有可预测的迭代次序。
代码:
package Collection;
import java.util.*;
//提高唯一性元素的查询效率,还想保证有序
//使用HashSet 的子类 LinkedHashSet
public class LinkedHashSetDemo_HashSet {
public static void main(String[] args){
//创建集合,不用子类的特有方法
Set set = new LinkedHashSet();
set.add("hdiw1");
set.add("hdiw1");
set.add("hdiw2");
set.add("hdiw3");
for(Iterator it = set.iterator();it.hasNext();){
System.out.println(it.next());
}
}
}
输出结果:
hdiw1
hdiw2
hdiw3//有序,查询快,唯一
解析:
哈希表与链表的联合。其实就是在哈希表中每个元素再存下一个元素的位置,获取时按照链表的地址索引就可以按照输出的顺序。