集合

集合

什么是集合?

集合是用来存储不同数据类型的容器。

集合的特点

  • 对象封装数据,对象多了也需要存储。集合用于存储对象。
  • 对象的个数确定可以使用数组,对象的个数不确定的可以使用集合。因为集合的长度是可以改变的。

集合与数组的区别

  • 数组的长度是固定的;集合的长度是可变的。
  • 数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
  • 数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同的数据类型。

常用的集合类有哪些?

Map接口和Collection接口是所有集合框架的父接口:

  1. Collection接口的子接口包括:Set接口和List接口;
  2. Map接口的实现类主要由:HashMap,TreeMap,Hashtable,ConcurrentHashMap等;
  3. Set接口的实现类主要有:HashSet,TreeSet,LinkedHashSet等;
  4. List接口的实现类主要有:ArrayList,LinkedList,Stack以及Vector等;

List,Set,Map三者的区别?List,Set,Map是否继承自Collection接口?List,Map,Set三个接口存取元素时,各有什么特点?

Java容器分为Collection和Map两大类,Collection集合的子接口有Set,List,Queue三种子接口。我们比较常用的是Set,List。Map接口不是collection的子接口。

Collection集合主要有List和Set两大接口

List:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的类有ArraysList,LinkedList和Vector。

Set:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素的唯一性。Set接口的常用实现类是HashSet,LinkedHashSet以及TreeSet。

Map是一个键值对集合,存储键,值和之间的映射。Key无序,唯一;value不要求有序,允许重复。Map没有继承与Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。

Map的常用实现类有:HashMap,TreeMap,HashTable,LinkedHashMap,ConcurrentHashMap。

集合框架底层数组数据结构

Collection

1.List

  • ArraysList :Object数组
  • Vector:Object数组
  • LinkedList:双向循环链表

2.Set

  • HashSet(无序,唯一):基于HashMap实现的,底层采用HashMap来保存元素
  • LinkedHashSet:LinkedHashSet继承于HashSet,并且其内部是通过LinkedHashMap来实现的。
  • TreeSet(有序,唯一):红黑树(自平衡的排序二叉树)

Map

  • HashMap:JDK1.8之前HashMap由数组+链表组成的,数组是Hashmap的主体,链表则是主要为了解决哈希冲突而存在的。JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认8)时,将链表转化为红黑树,以减少搜索时间
  • LinkedHashMap:LinkedHashMap继承于HashMap。
  • HashTable:数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的
  • TreeMap:红黑树(自平衡的排序二叉树)

那些集合是线程安全的?

  • vector:就比arraylist多了个同步化机制(线程安全),效率低,不建议使用。
  • statck:堆栈类,先进后出
  • hashtable:就比hashmap多了个线程安全
  • enumeration:枚举,相当于迭代器

遍历一个List有哪些种不同的方式?

  • for循环遍历:基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置上的元素,当读取到最后一个元素后停止。
  • 迭代器便利:Iterator;
  • foreach循环遍历。

ArrayList的优缺点

优点:底层是以数组实现,是一种随机访问模式。查找速度非常快。
在顺序添加一个元素的时候非常方便
缺点:删除元素的时候,需要做一次元素复制操作。如果要复制元素很多,那么就会比较耗费性能
插入元素的时候,也需要做一次元素复制操作。

ArrayList比较适合顺序添加,随机访问的场景。

如何实现数组和List之间的转换?

数组转List:使用Arrays.asList(array)进行转换。
List转数组:使用List自带的toArray()方法。

ArrayList和LinkedList的区别是什么?

  • 数据结构实现:ArrayList是动态数组的数据结构实现,而LinkedList是双向链表的数据结构实现。
  • 随机访问效率:ArrayList比LinkedList在随机访问的时候效率要高,因为LinkedList是线性的数据存储方式,所以移动指针从前往后依次查询。
  • 增加和删除的效率:在非首尾的增加和删除操作,LinkedList要比ArrayList效率要高,因为ArrayList增删操作要影响数组内的其他数据的下标。
  • 内存空间占用:LinkedList比ArrayList更占用内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
  • 线程安全:ArrayList和LinkedList都是不同步的,也就是线程不安全的。

总结:在需要频繁读取数据集合中的元素时,更推荐使用ArrayList,而在插入和删除操作较多时,更推荐使用LinkedList。

List和Set的区别

List,set都是继承自Collection接口

List特点:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的类由ArrayList,LinkedList和Vector。

Set特点:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复的元素,只允许存入一个null元素,必须保证元素的唯一性。Set接口常用的实现类是HashSet,LinkedHashSet以及TreeSet。

另外List支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为它无序,无法用下标来取得想要的值。

总结:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组相同,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

Set接口

实现原理

HashSet是基于HashMap实现的,HashSet的值存放于HashMap的key上,HashMap的value统一为Present,因此HashSet的实现比较简单,相关HashSet的操作,基本上是调用底层HashMap的相关方法来完成,HashSet不允许重复的值。

HashSet如何健康检查重复?HashSet是如何保证数据不可重复的?

向HashSet中的add()元素时,判断元素是否存在的依据,不仅要比较hash值,同时还要结合equles方法比较。

HashSet中的add()方法会使用HashMap的put()方法。

HashMap的key时唯一的,由源码可以看出HashSet添加进去的值就是作为HashMap的key,并且在HashMap中如果K/V相同时,会用新的V覆盖掉旧的V,然后返回旧的V。所以不会重复(HashMap比较key是否相等是先比较hashcode再比较equals)。

HashCode()和equals()的相关规定

  1. 如果两个对象相等,则hashcode一定也是相等的
  2. 两个对象相等,对两个equals方法返回true
  3. 两个对象有相等的hashcode值,他们也不一定是相等的
  4. 综上,equals方法被覆盖,则hashCode方法也必须重写
  5. hashcode()的默认行为是对堆上的对象产生独特值。如果没有重谢hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

HashMap是如何解决哈希冲突的?

Hash:哈希,一般翻译为散列,就是把任意长度的输入通过散列算法,变换成固定长度的散列值(哈希值)。

什么是哈希冲突?

当两个不同的输入值,根据统一单列函数计算出相同的散列值的现象,我们旧把它叫做碰撞(哈希碰撞)。

HashMap的数据结构

在Java中,保存数据有两种比较简单的数据结构:数组和链表。
数组的特点:寻址容易,插入和删除困难;
链表的特点:寻址困难,但插入和删除容易;

所以我们将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做链地址法的方式可以解决哈希冲突。

如何使用Object作为HashMap的Key,应该怎么办呢?

重写hashCode和equals方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值