Collection<E>:代表单列集合,每个元素(数据只包含)一个值,集合中存储的是对象的地址。
1.List<E>:添加的元素有序(添加的元素顺序和集合中的是一致的)、可重复、有索引
(1) ArrayList<E>:有序、可重复、有索引,基于数组实现
①特点:
-
查询速度快(根据索引查询数据快):查询数据通过地址值和索引定位,查询任意数据耗时相同
-
删除效率低:可能需要把后面很多的数据进行前移
-
添加效率极低:可能需要把后面很多的数据后移,再添加元素;或可能需要进行数组扩容
②构造:
-
利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
-
添加第一个元素时,底层会创建一个新的长度为10的数组
-
存满时,会扩容1.5倍
-
如果一次添加多个元素,1.5倍放不下,则新创建数组的长度以实际为准
③应用场景:
-
根据索引查询数据
(2)LinkedList<E>:有序、可重复、有索引,基于双链表实现
①特点:
-
查询慢,增删相对较快,但对首位元素进行增删改查的速度是极快的
②应用场景:
-
可以用来设计队列(先进先出),用addLast(在尾部添加元素)来入队,removeFirst来出队
-
可以用来设计栈(先进后出),用addFirst(在头部添加元素)或push(实际调用的也是addFirst方法)来压栈,removeFirst或pop(实际调用的也是removeFirst方法)来出栈
2.Set<E>:无序(添加的顺序和获取出的数据顺序不一致)、不可重复、无索引
-
HashSet<E>:无序、不可重复、无索引
-
HashSet底层原理
-
预先了解:哈希值
-
一个int类型的数值,Java中每个对象都有一个哈希值
-
Java中的所有对象,都可以调用Oject类提供的hashCode方法,返回该对象自己的哈希值
-
特点:
-
同一个对象多次调用hashCode()方法返回的哈希值是相同的。
-
通过的对象,他们的哈希值一般不相同,但也有可能相同(哈希碰撞)
-
-
-
基于哈希表实现
-
哈希表是一种增删改查数据,性能都比较好的数据结构
-
JDK8 之前,哈希表=数组+链表
-
JDK8 开始,哈希表=数组+链表+红黑树
-
红黑树是可以自平衡的二叉树,是一种增删改查数据性能相对较好的结
-
-
-
如果希望两个内容一样的对象是重复的,需要重写equals和hashCode方法
-
-
-
LinkedHashSet<E>:有序、不可重复、无索引(也可以是HashSet的一个子类)
-
底层原理
-
依然是基于哈希表(数组、链表、红黑树)实现
-
不过,它的每个元素都额外多了一个双链表的机制记录它前后元素的位置
-
-
-
TreeSet<E>:按照大小默认升序排序、不可重复、无索引
-
底层基于红黑树实现
- 注意:
-
对于数值类型:Integer,Double,默认按照数值本身的大小进行排序
-
对于字符串类型:默认按照首字符的编号升序排序
-
对于自定义类型对象(如Studnet),TreeSet默认是无法直接排序的,需要指定排序规则
-
方式1:让自定义的类实现Comparable接口,重写里面的compareTo方法来指定比较规则
public class Student implements Comparable<Student>{ @Override public int compareTo(Student o) { //如果认为左边对象大于右边对象返回正整数 //如果认为左边对象小于右边对象返回负整数 //如果认为左边对象等于右边对象返回0 //按照年龄升序:如果this.age大于o.age(即返回正数),this.age会向后抛;反之则不变 return this.age-o.age; } private String name; private int age; private double height; }
- 方式2:通过调用TreeSet集合有参构造器,设置Comparator对象(比较器对象,用于指定比较规则)
//如果有多个比较器对象,TreeSet会选择自己自带的比较器对象进行排序 Set<Student> students=new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { //按照身高升序 return Double.compare(o1.getHeight(),o2.getHeight()); } });
-
-
-