Set集合
-
List集合:Arraylist,Linklist以及Vector;
-
Vector是从jdk1.0版本开始使用,Arraylist是在jdk1.2以后开始使用,前者是为了注重线程安全,以至于性能不高,后者注重,是非线程安全的。在使用时,vector需要扩充长度时,会直接扩充旧长度的一倍,而Arraylist在源码中扩充是自己的长度是根据自己的旧长度加上自己长度向右移1位,右移n为就是除以2的n次方,换句话来说就是扩充50%。另外,Arraylist的默认长度是在第一次调用add方法时,长度才初始化的,默认最小长度为16.
-
-
list集合:可重复,有序的
-
set集合:唯一,无序的
-
常用子类
- HashSet(去重复)
- TreeSet(可排序)
- LinkedHashSet(有序)
-
-
和List集合的方法大同小异,只不过因为Set集合是无序的,没有下标的,所以跟下标有关系的方法没有。
HashSet的原理
-
HashSet的作用:去除重复元素
-
-
同样的HashSet的初始容量是16,而负载因子,则是集合可达到的阈值,每次集合的个数有变动时,都会判断当前集合的大小是否大于或等于阈值(容量*负载因子),所以第一次当集合大小为12时,会进行扩容。
-
底层实现:底层是依托在HashMap实现的,而Map集合,是由一个个kv键值对组成的,而HashSet的元素存在于HashMap的key上。每次添加元素都是依托于hashCode方法和equals方法来判断新元素是否相同的,所以如果我们需要添加一个自己的类的话,这个类得重写equals()和hashCode()方法,通过这两个方法进行判断,如果不是同一个元素则会直接添加,反之则不会添加。不过如果想要添加相同的元素,那么就重写这两个方法,并返回false,让集合认为不是用一个元素就行了。
Collection集合(List/Set的遍历)
遍历集合:把集合中的元素一个一个拿出来
-
List集合
-
第一种普通for循环
for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); }
-
第二种迭代器
//首先获取当前集合的迭代器对象 Iterator iterator = list.iterator(); //通过判断迭代器的.next方法进行遍历 //这样做不需要知道集合的下标,可以直接从头到尾进行遍历 while(iterator.hashNext()){ //判断是否为空,不为空则输出,为空跳出循环,遍历结束 System.out.println(iterator.next()); }
-
增加for循环
//底层上就是使用的迭代器实现的,因为迭代器的代码相对于比较复杂 //jdk为了帮助编程,所以添加了foreach循环 for(数据类型 数据名:集合名){ System.out.println(数据名); }
-
特别注意:迭代器在遍历的过程中,会调取一个方法,然后是自己的modCoount=集合的modCount。然后每次进行遍历时,都会判断这两个数是否相等,这么做的原因是,防止它在遍历时,你对集合进行修改,导致输出不一,所以会加这个判断。
-
TreeSet排序
-
TreeSet底层使用红黑树:左<根<右 有序的
-
红黑树为了达到左右节点的平衡会进行左旋,右旋的操作
-
TreeSet可排序的,创建TreeSet
-
-
TreeSet实现排序是依托比较器Comparator,对于新元素与老元素的比较,然后判断需要放的位置,比较器比较的方法是public int compareTo(T o);实现的规则是,调用改方法的元素this与被比较元素o进行ASCII值的减法,因此返回int类型;所以如果结果等于0表示两个元素相等,则不添加,如果小于0 ,则新元素添加在左边,反之添加在右边。
-
因为compareTO()方法是写死的,所以如果我们需要创建自己的类进行比较时,需要用到另一种方式。
-
获取指定的Comparator比较器,在调用TreeSet的无参构造方法时,直接指定一个比较器new TreeSet(比较器对象);比较器对象也可以写成匿名内部类,这样可以根据需求进行自定义。
-
-
又或者可以在自定义的类中继承接口Comparable<对象类型>,然后在类中重写compareTo()方法。
-