1,TreeSet--自然排序
1,让类实现comparable接口
2,重写compareTo方法,在这个方法中指定比较规则(排序规则)
3,根据方法的返回值,来组织排序规则
负数,往左走;正数,往右走;如果是0,就不存
4,第一个元素是树根,其他的先跟这个比较,然后再依次比较
正序排列:this-o;倒序排列:o-this
取出顺序:左中右的顺序
2,TreeSet细节补充--保存重复元素
要用compareTo进行字符串的比较,在年龄相同的情况下可以进行排序,按照的是字典顺序
如果要保存重复元素,就可以直接返回1或者-1;
3,第二种排序方法---比较器排序---自己定义排序规则,一些特别的排序方式
特点:如果同时具备自然排序与比较器排序,优先按照比较器排序的规则进行操作
1,在treeset集合的构造方法里面,传入compare接口的实现类对象
2,重写里面compare方法,然后快捷改成lambda表达式就可以简化结构了
3,根据方法的返回值,来组织排序规则
负数:左;正数:右;0:不存
4,HashSet
4.1:底层采用哈希表,能够确保元素的唯一性(不会排序)
哈希表是一种对增删改查数据性能都较好的结构
JDK8之前:数组+链表
JDK8之后:数组+链表+红黑树
HashSet如果要保证元素唯一,需要同时重写HashSet和equals方法
4.2:hashset方法与equals方法
1,当添加对象的时候,会先调用对象的hashset方法计算出一个应该存入的索引位置,查 看该位置上是否存在元素
2,不存在:直接存;存在:调用equals方法比较内容
false:内容不相同,存;true:内容相同,不存
4.3:hashset方法改造
object中的方法
功能:返回一个哈希值
哈希值:就是一个int类型的随机值,java中每一个对象都有一个哈希值
根据对象内容生成的hash值,不同的对象,hash值也可能相等---哈希碰撞
public native int hashcode():调用底层c++代码计算出来的一个随机数(常被称作地址值)
上面就是不重写方法发生的事情,所以数据会重复,随机值不同,索引不同
可以用对象中的属性值来计算哈希值,链表就不长,而且减少equals的调用次数
5,HashSet集合的底层原理
JDK8之前的哈希表:数组+链表
1,创建一个默认长度16的数组,默认加载因子为0.75,数组名为table
2,使用元素的哈希值对数组的长度做运算计算出应存入的位置(哈希值取余就得到索引)
3,判断当前位置是否为null,如果是的话直接存入
4,如果不是null,表示有元素,则调用equals方法比较
相等,则不存;不相等,则存
jdk8之前,新元素占老元素的位置,老元素挂在新元素下面,头插法
jdk8之后,新元素挂在老元素下面,尾插法
5,扩容:当元素的数量到达 默认长度*默认加载因子 的时候,就进行扩容,扩容为原来的2倍大小
JDK8之后:数组+链表+红黑树
1,如果某一个链表挂载结点的数量大于8(阈值)且数组长度大于64的时候,这个链表就会转化成红黑树,查询性能就会提高
2,底层数组名也不再是table而是变成了Segment[ ]
6,LinkedHashSet集合
LinkedHashSet的底层原理
依然是基于哈希表实现的
但是,它的每一个元素都额外多了一个双链表的机制记录它前后元素的位置
7,collection接口小总结

8,可变参数
可变参数用在形参中可以接收多个数据
可变参数的格式:参数类型...参数名称--三个点
传输参数十分灵活,方便,可以不传输参数,可以传输一个或多个,也可以传输一个数组
注意事项:
1,可变参数,在方法里面只能有一个,因为一个就把数据吃完了,后面啥也没有
2,如果方法中除了可变参数还有其他的参数,需要将可变参数放到最后
可变参数本质就是一个数组
9,Collections集合工具类
Collections并不属于集合,是用来操作集合的工具类
public static <T> boolean addAll(Collection<? super T> c, T... elements) 给集合对象批量添加元素
public static void shuffle(List<?> list) 打乱 List 集合元素的顺序
public static <T> void max/min(Collection<T> coll) 根据默认的自然排序获取最大/小值
public static <T> void sort(List<T> list) 将集合中元素按照默认规则排序