集合- new TreeSet<>() -可排序集合
TreeSet集合存储元素特点:
- 无序不可重复的,但是存储的元素可以自动按照大小顺序排序!称为:可排序集合。
- 无序:这里的无序指的是存进去的顺序和取出来的顺序不同。并且没有下标。
- TreeSet集合底层实际上是一个TreeMap;TreeMap集合底层是一个二叉树。
- 放到TreeSet集合中的元素,等同于放到TreeMap集合key部分了。
对自定义的类型来说,TreeSet可以排序吗?
- 以下程序中对于Vip类型来说,无法排序。因为没有指定Vip对象之间的比较规则。 谁大谁小并没有说明啊。
- 以下程序运行的时候出现了这个异常:
- java.lang.ClassCastException:
- cannot be cast to class java.lang.Comparable
- 出现这个异常的原因是:
- 类没有实现java.lang.Comparable接口。
- 或者实现java.util.Comparator比较器
TreeSet集合中元素可排序的两种方式:
- 放到TreeSet或者TreeMap集合key部分的元素要想做到排序,包括两种方式:
- 第一种:放在集合中的元素实现java.lang.Comparable接口。
- 第二种:在构造TreeSet或者TreeMap集合的时候给它传一个比较器对象。
Comparable和Comparator怎么选择呢?
- 当比较规则不会发生改变的时候,或者说当比较规则只有1个的时候,建议实现Comparable接口。
- 如果比较规则有多个,并且需要多个比较规则之间频繁切换,建议使用Comparator接口。
- Comparator接口的设计符合OCP原则。
第一种方式Object实体对象;实现Comparable接口:
- 创建一个无序不可重复的,但可以排序的TreeSet集合
- TreeSet<Vip> vip = new TreeSet<>();
- 实体对象要实现Comparable<> 接口,接口后一定要有泛型,不然遍历的时候数据就只能拿到第一个
- public class Vip implement Comparable<Vip>{
- 实现Comparable 接口里面的方法
- 重写构造方法,需要提供有参构造和无参构造
- 重写toString()方法
- 重写排序规则compareTo:!!!!!很重要
- public int CompareTo(Vip v){}
- String类型,可以直接比JDK里面已经实现不需要重写String比较规则。调用compareTo来完成比较。
- }
public class Vip implements Comparable<Vip> { public String name; public Integer age; //重写Comparable 方法 //构造方法 public Vip(){} public Vip ( String name , Integer age ) { this.name = name; this.age = age; } //重写toString()方法 @Override public String toString () { return "Vip{" + "name='" + name + '\'' + ", age=" + age + '}'; } //compareTo:排序规则 public int compareTo(Vip v){ if(this.age==v.age){ return this.name.compareTo(v.name); }else{ return this.age-v.age; } } }
java.util.Comparator 比较器
import java.util.Comparator; import java.util.TreeSet; public class VipComparator { public static void main ( String[] args ) { //匿名内部类重写java.util.Comparator TreeSet<Vip> vips = new TreeSet<>(new Comparator<Vip>() { @Override public int compare ( Vip o1 , Vip o2 ) { if(o1.age==o2.age){ return o1.name.compareTo(o2.name); }else { return o1.age-o2.age; } } }); 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); } } }
HashSet 实际上对应HashMap
TreeSet 实际上对应TreeMap