TreeSet
1、TreeSet集合底层实际上是一个TreeMap
2、TreeMap集合底层是一个二叉树。
3、放到TreeSet集合中的元素,等同于放到TreeMap集合key部分了。
4、TreeSet集合中的元素:无序不可重复,但是可以按照元素的大小顺序自动排序。
称为:可排序集合。
public classTreeSetTest02 {public static voidmain(String[] args) {//创建一个TreeSet集合
TreeSet ts = new TreeSet<>();//添加String
ts.add("zhangsan");
ts.add("lisi");
ts.add("wangwu");
ts.add("zhangsi");
ts.add("wangliu");//遍历
for(String s : ts){//按照字典顺序,升序!
System.out.println(s);
}
TreeSet ts2 = new TreeSet<>();
ts2.add(100);
ts2.add(200);
ts2.add(900);
ts2.add(800);
ts2.add(600);
ts2.add(10);for(Integer elt : ts2){//升序!
System.out.println(elt);
}
}
}
对自定义的类型来说,TreeSet可以排序吗?
以下程序中对于Person类型来说,无法排序。因为没有指定Person对象之间的比较规则。
谁大谁小并没有说明啊。
以下程序运行的时候出现了这个异常:
java.lang.ClassCastException:
class com.bjpowernode.javase.collection.Person
cannot be cast to class java.lang.Comparable
出现这个异常的原因是:
Person类没有实现java.lang.Comparable接口。
packagecom.bjpowernode.javase.collection;importjava.util.TreeSet;public classTreeSetTest04 {public static voidmain(String[] args) {
Customer c1= new Customer(32);
Customer c2= new Customer(20);
Customer c3= new Customer(30);
Customer c4= new Customer(25);//创建TreeSet集合
TreeSet customers = new TreeSet<>();//添加元素
customers.add(c1);
customers.add(c2);
customers.add(c3);
customers.add(c4);//遍历
for(Customer c : customers){
System.out.println(c);
}
}
}//放在TreeSet集合中的元素需要实现java.lang.Comparable接口。//并且实现compareTo方法。equals可以不写。
class Customer implements Comparable{intage;public Customer(intage){this.age =age;
}//需要在这个方法中编写比较的逻辑,或者说比较的规则,按照什么进行比较!//k.compareTo(t.key)//拿着参数k和集合中的每一个k进行比较,返回值可能是>0 <0 =0//比较规则最终还是由程序员指定的:例如按照年龄升序。或者按照年龄降序。
@Overridepublic int compareTo(Customer c) { //c1.compareTo(c2);//this是c1//c是c2//c1和c2比较的时候,就是this和c比较。
/*int age1 = this.age;
int age2 = c.age;
if(age1 == age2){
return 0;
} else if(age1 > age2) {
return 1;
} else {
return -1;
}*/
//return this.age - c.age;//=0 >0 <0
return c.age - this.age;
}publicString toString(){return "Customer[age="+age+"]";
}
}
packagecom.bjpowernode.javase.collection;importjava.util.TreeSet;/*先按照年龄升序,如果年龄一样的再按照姓名升序。*/
public classTreeSetTest05 {public static voidmain(String[] args) {
TreeSet vips = new TreeSet<>();
vips.add(new Vip("zhangsi", 20));
vips.add(new Vip("zhangsan", 20));
vips.add(new Vip("king", 18));
vips.add(new Vip("soft", 17));for(Vip vip : vips){
System.out.println(vip);
}
}
}class Vip implements Comparable{
String name;intage;public Vip(String name, intage) {this.name =name;this.age =age;
}
@OverridepublicString toString() {return "Vip{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}/*compareTo方法的返回值很重要:
返回0表示相同,value会覆盖。
返回>0,会继续在右子树上找。【10 - 9 = 1 ,1 > 0的说明左边这个数字比较大。所以在右子树上找。】
返回<0,会继续在左子树上找。*/@Overridepublic intcompareTo(Vip v) {//写排序规则,按照什么进行比较。
if(this.age ==v.age){//年龄相同时按照名字排序。//姓名是String类型,可以直接比。调用compareTo来完成比较。
return this.name.compareTo(v.name);
}else{//年龄不一样
return this.age -v.age;
}
}
}
TreeSet集合中元素可排序的第二种方式:使用比较器的方式。
最终的结论:
放到TreeSet或者TreeMap集合key部分的元素要想做到排序,包括两种方式:
第一种:放在集合中的元素实现java.lang.Comparable接口。
第二种:在构造TreeSet或者TreeMap集合的时候给它传一个比较器对象。
Comparable和Comparator怎么选择呢?
当比较规则不会发生改变的时候,或者说当比较规则只有1个的时候,建议实现Comparable接口。
如果比较规则有多个,并且需要多个比较规则之间频繁切换,建议使用Comparator接口。
Comparator接口的设计符合OCP原则。
packagecom.bjpowernode.javase.collection;import java.util.*;/*java.util.Collection 集合接口
java.util.Collections 集合工具类,方便集合的操作。*/
public classCollectionsTest {public static voidmain(String[] args) {//ArrayList集合不是线程安全的。
List list = new ArrayList<>();//变成线程安全的
Collections.synchronizedList(list);//排序
list.add("abf");
list.add("abx");
list.add("abc");
list.add("abe");
Collections.sort(list);for(String s : list){
System.out.println(s);
}
List wuGuis = new ArrayList<>();
wuGuis.add(new WuGui2(1000));
wuGuis.add(new WuGui2(8000));
wuGuis.add(new WuGui2(500));//注意:对List集合中元素排序,需要保证List集合中的元素实现了:Comparable接口。
Collections.sort(wuGuis);for(WuGui2 wg : wuGuis){
System.out.println(wg);
}//对Set集合怎么排序呢?
Set set = new HashSet<>();
set.add("king");
set.add("kingsoft");
set.add("king2");
set.add("king1");//将Set集合转换成List集合
List myList = new ArrayList<>(set);
Collections.sort(myList);for(String s : myList) {
System.out.println(s);
}//这种方式也可以排序。//Collections.sort(list集合, 比较器对象);
}
}class WuGui2 implements Comparable{intage;public WuGui2(intage){this.age =age;
}
@Overridepublic intcompareTo(WuGui2 o) {return this.age -o.age;
}
@OverridepublicString toString() {return "WuGui2{" +
"age=" + age +
'}';
}
}