java单列集合学习
- List接口的实现类
- ArrayList:动态数组实现,允许重复元素
- LinkedList:双向链表实现,允许重复元素
- Set接口的实现类
- HashSet:基于哈希表实现,不允许重复元素
- LinkedHashSet:基于哈希表和链表实现,不允许重复元素,保持插入顺序
- TreeSet:基于红黑树实现,不允许重复元素,元素自动排序
Collection
Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的
collection方法
- 把给定的对象添加到当前集合中
1. 如果我们向List系列集合中添加数据,那么方法永远会返回true,因为List系列是允许元素重复
2.如果我们向Set系列集合中添加数据,那么方法会根据是否存在而返回true或false,因为Set系列是不允许元素重复的
1 | Collection<E> coll = new ArrayList<> (); |
- 清空集合中所有的元素
1 | Collection<E> coll = new ArrayList<> (); |
- 把给定的对象在当前集合中删除
1.这个方法会返回一个布尔类型的值,当要删除的元素不存在,就会返回false
2. 因为Collection里面定义的是List和Set共性的方法,所以不能通过索引进行删除,只能通过元素的对象进行删除
1 | Collection<E> coll = new ArrayList<> (); |
- 判断当前集合中是否包含给定的对象
在源码中contains方法是依赖equals方法进行判断是否存在,因此如果集合中存储的是自定义对象,在JavaBean中一定要重写equals方法
1 | Collection<E> coll = new ArrayList<> (); |
- 判断当前集合是否为空
1 | Collection<E> coll = new ArrayList<> (); |
- 返回集合元素中个数/集合的长度
1 | Collection<E> coll = new ArrayList<> (); |
Collections
Collections是集合的工具类
- 打乱集合中的元素
1 | Collection<E> coll = new ArrayList<> (); |
- 获取集合中的最大值
1 | Collection<E> coll = new ArrayList<> (); |
- 批量添加元素
1 | Collection<E> coll = new ArrayList<> (); |
- 排序
1 | Collection<E> coll = new ArrayList<> (); |
- 以二分查找查找元素
1 | Collection<E> coll = new ArrayList<> (); |
- 拷贝集合中的元素
1 | Collection<E> coll = new ArrayList<> (); |
- 交换集合指定位置的元素
1 | Collection<E> coll = new ArrayList<> (); |
遍历方法
迭代器遍历
1.迭代器在遍历集合的时候不依赖索引
2. 迭代器遍历完毕,指针不会复位,如果还要进行遍历,则需要重新获取一个迭代器对象
3. 一个循环中只能使用一次next方法,不然可能会报NoSuchElementException错误
4. 迭代器在遍历的时候,不能用集合的方法进行增加和删除,但是可以用迭代器提供的remove方法进行删除
1 | Collection<String> collection = new ArrayList<>(); |
增强for遍历
增强for的底层就是迭代器,为了简化迭代器的代码而存在的
1 | Collection<E> collection = new ArrayList<>(); |
lambda表达式
lambda表达式允许以简洁的语法编写匿名内部类。Lambda表达式主要用于实现单个抽象方法的接口,这种接口被称为函数式接口(Functional Interface),这是一个只有一个抽象方法的接口。
1 | Collection<E> collection = new Collection<> (); |
List
List集合特有方法
- 在集合的指定位置插入指定的元素
1 | ArrayList<E> list = new ArrayList<> (); |
- 删除指定索引处的元素,返回被删除的元素
1 | ArrayList<E> list = new ArrayList<> (); |
1 | ArrayList<Integer> list = new ArrayList<> (); |
- 修改指定索引处的元素,返回被修改的元素
1 | ArrayList<E> list = new ArrayList<> (); |
- 返回指定索引处的元素
1 | ArrayList<E> list = new ArrayList<> (); |
遍历方法
- 迭代器遍历
- 增强for循环
- lambda表达式
- 普通for循环
- 列表迭代器(可以在遍历过程中添加,修改元素)
列表迭代器还可以反向遍历集合,用hasPrevious() 和 previous()
。
1 | ArrayList<E> list = new ArrayList<> (); |
ArrayList
ArrayList集合原理:
- 利用空参创建的集合,在底层创建一个默认长度为0的数组
- 添加第一个元素时,底层会创建一个新的长度为10的数组
- 当数组存满时,会扩容1.5倍
- 如果一次添加多个元素,1.5倍还放不下,则创建数组的长度和实际需要的长度一致
LinkedList
LinkedList的底层数据类型是双链表,因此有很多首尾操作的特有API
在列表开头插入特定的元素
public void addFirst(E e)
将指定的元素追加到列表的末尾
public void addLast(E e)
返回列表中的第一个元素
public E getFirst()
返回列表中的最后一个元素
pubic E getLast()
在列表中删除并返回第一个元素
public E removeFirst()
在列表中删除并返回最后一个元素
public E removeLast()
Set
HashSet
哈希值:
- 根据hashCode方法算出来的int类型的整数
- 所有对象都有哈希值,默认使用的地址值进行计算
- 一般来说,会重写hashCode方法,利用对象内部的属性值计算哈希值
- 在小部分情况下,不同属性值或者不同地址值计算出来的哈希值可能一样(哈希碰撞)
HashSet底层原理:
- 创建一个默认长度16,默认加载因为0.75的数组,数组名为table
- 根据元素的哈希值跟数组的长度计算出应存入的位置
- 判断当前位置是否为null,如果是null直接存入
- 如果位置不为null,表示有元素,则调用equals方法比较属性值
- 一样:不存;不一样:存入数组,形成链表,新元素直接挂在老元素下面(JDK8以前新老元素位置相反)
LinkedHashSet
LinkedHashSet底层原理:底层数据结构依然是哈希表,只是每个元素又额外多了一个双链表的机制记录存储的顺序,因此有序(存储和取出的元素顺序一致)
TreeSet
TreeSet的底层原理:这是基于红黑树的数据结构实现排序的,增删改查性能都较好
Treeset集合默认的排序规则:
- 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
- 对于字符,字符串类型:按照字符在ASCII码表中的数字升序进行排序
两种更改排序的方法:
- 自然排序:Javabean类实现Comparable接口指定比较规则
1 | public clss T implements Comparable<T> { |
- 比较器排序:创建TreeSet对象时候,传递比较器Comparator指定规则
使用原则:默认使用第一种,如果第一种不能满足当前要求,才使用第二种
1 | TreeSet<String> ts = new TreeSet<>(new Comparator<String>() { |
使用场景
- 想要集合中元素可重复
ArrayList集合,基于数组的
- 想要集合中元素去重
HashSet集合,基于哈希表的
- 想要集合中元素可重复,而且当前增删操作明显多于查询
LinkedList集合,基于链表的
- 想要集合中元素去重,并且保证存取顺序
LinkedHashSet集合,基于哈希表和双链表,效率低于HashSet
- 想要集合中元素进行排序
TreeSet集合,基于红黑树,后续也可以用List集合实现排序