集合框架概览

集合

什么是集合

集合是用来存储对象的容器,定义了对多个对象进行操作的常用方法,实现了数组的功能,位于java.util.*下

集合和数组的区别

  1. 数组长度不可变,集合长度可变
  2. 数组可以存放基本数据类型和引用类型,集合只能存放引用类型

介绍一下Java中的集合体系

​ jave中的集合主要分为两大类,一类为Collection,一类为map;Collection又主要分为List和Set,其中List为保证插入顺序,且可以存放重复值的集合,他的代表是ArrayList;而Set是不保证顺序,且不能有重复值的集合,他的代表是HashSet;Map是Key - Value方式存储值的一种集合,他的代表是HashMap;

Collection集合接口

在这里插入图片描述

Collection接口常用的方法

  1. add添加一个对象
  2. addAll将一个集合中的所有对象添加到此集合
  3. clear清空此集合所有对象
  4. contains检查此集合中是否包含某个对象
  5. isEmpty判断此集合是否为空
  6. remove移除某个元素
  7. size返回集合元素个数
  8. toArray将此集合转换为数组
  9. equals比较此集合是否与指定对象相等
  10. reverse反转集合中的元素
  11. sort升序排序
  12. shuffle随机重置元素顺序
  13. binarySearch 查找集合中的元素是否存在,位置下标
  14. copy 复制集合到新集合
    这里需要注意的是需要先给新集合所有元素添加为0
  15. toArray 集合转化为数组
  16. Arrays.asList 数组转化为集合
    转化的集合为受限集合,不能添加删除
    基本数据类型数组转化为集合需要先变为包装类

集合遍历方式

增强for循环

iterator迭代器

注意: 在使用迭代器时不能使用Collection接口的方法

  1. hasNext(): 有没有下一个元素
  2. next(): 获取下一个元素
  3. remove(): 移除元素当前

一、list接口

有序,有下标,可以重复

list中的方法:

  1. add: 指定在某个位置插入对象
  2. addAll: 指定在某个位置插入一个集合
  3. get: 获取指定位置的元素
  4. subList: 获取某一段index之间的元素(注意含头不含尾)
  5. indexOf: 返回指定元素第一次出现的索引
  6. listIterator: 列表迭代器,比Collection的迭代器功能更强大

遍历方式:

  1. for
  2. foreach
  3. iterator
  4. listIterator: 通过hasPrevious()可以逆序遍历,也可以在迭代的时候增删改

注意: 删除数字的时候,会误以为删除下标为数字的元素,需要对数字进行强转包装类


1.1ArrayList

底层基于数组,所以查询快,增删慢(增删慢是因为要维护下标),线程不安全

底层分析:
默认容量是10(当我们调用无参构造创建了ArrayList,并且没有添加元素的时候长度是0,添加了元素就会扩容为10)
就是一个elementData数组
每次扩容1.5倍(位运算右移了一位)


1.2Vector

底层基于数组,查询快,增删慢,线程安全(使用了Synchronized修饰方法)


1.3LinkedList

底层基于双向链表,查询慢(需要遍历所有),增删快

底层分析:
通过first.last.newNode节点实现

二、set接口

无序,无下标,不可以重复


2.1HashSet

底层结构: 哈希表(数组+链表+红黑树),就是HashMap

存储原理: 先根据HashCode计算出存储在数组中得位置,然后根据equals判断是否重复,如果重复拒绝存储,如果不重复存储到链表中,当链表元素等于8时转为为红黑树,当小于6时转化为链表

基于HashMap


2.2TreeSet

底层结构: 红黑树

存储原理: 因为是数型结构,所以必须要指定排序规则
实现Comparable接口
指定Comparator定制比较器

基于TreeMap

三、Map接口

用于存储任意键值对

key: 无序,无下标,不可重复(注意: 当key相同时会覆盖前一个Value)

value: 无序,无下标,可以重复

Map接口常用方法:

  1. put
  2. get
  3. keySet() 返回一个Set集合,含有所有的key
  4. Collection values()
  5. set<Map.entry<K,V>>

Map接口的遍历

keySet方法

通过keySet方法拿到所有key的一个set集合
使用foreach遍历set集合,通过map.get(Key)拿到所有的value

entrySet方法

通过entrySet方法拿到entries的Set集合(entry就是一个key-value映射)
使用foreach遍历Set集合,通过map.getKey拿到Key,通过map.getValue拿到Value

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2VyY1J7h-1615477629001)(1615464855818.png)]


3.1HashMap

基本概念

存储结构: 哈希表(数组+链表+红黑树)

线程不安全,允许null作为Key或Value

默认初始容量: 16

默认加载因子: 0.75

判断重复的标准是HashCode和Equals,所以我们在使用自定义类型的的时候需要重写

源码分析:

HashMap刚创建的时候table是null,当添加第一个元素之后扩容为16

当元素个数大于阈值(16*0.75=12)时,进行2倍扩容

java1.8之后当链表长度大于等于8并且元素个数大于等于64的时候,链表才会转化为红黑树,当小于等于6时又转化为链表

java1.8之后采用尾插,为什么要使用尾插,因为保证安全,头插会使链表顺序翻转,造成死循环


3.2HashTable

线程安全的,不允许为null

初始容量: 11

Properties

HashTable的子类,要求Key,Value都是String,通常用于配置文件的读取


3.3TreeMap

实现了SortedMap,可以对Key排序

注意: 使用的时候需要指定排序规则(Comparable或Comparator )

如果需要从一个List集合中频繁的删除和添加元素,是选择ArrayList还是LinkedList?为什么?

频繁添加和删除选择使用LinkedList;

  • ArrayList的底层是数组,数组具有索引,所以他可以快速定位元素,查询效率较快。但是数组在内存中是一段连续的内存空间,删除和添加会涉及到内存空间的移位和扩容操作,所以添加和删除的效率低下;

  • 而LinkedList的底层使用的是双向链表的结构;这种结构不要求在内存空间中连续,只需要前后指定上下个节点的引用位置即可;查询时需要遍历整个集合,所以效率较慢,但添加和删除只需要改变引用即可,所以添加和删除效率较快;

什么是Hash冲突(碰撞)

​ Hash冲突是指的是,两个不同的值根据Hash算法得到的Hash值一样,这种情况叫做Hash冲突;我们一般选择使用拖链表、再Hash、开发寻址、或者创建冲突区来解决Hash冲突;

HashMap为什么要使用链表,又为什么要使用红黑树

​ HashMa是使用的Hash来计算元素存储的位置的,但因为Hash冲突的缘故,所以需要使用到链表结构来解决Hash冲突的元素存储问题;

使用红黑树是为了解决,当某些节点Hash冲突过多,链表拖的过长,导致查找效率较慢的情况,使用红黑树可以有效提升查询效率。

HashMap是否是线程安全的,如果不是,那么在多线程环境中我们应该使用哪个集合?

​ HashMap的线程是不安全的,HashTable是线程安全的HashMap,但因为他低下的效率已经过时不用了。在当前开发环境下,如多线程环境我们推荐使用ConcurrentHashMap。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值