了解Java集合原理

Java集合容器概述

1.什么是集合

  • 集合就是一个放数据的容器,准确的说就是放数据对象引用的容器
  • 集合类存放的都是数据的引用,而非数据本身
  • 集合主要有三种 set、list、map
    • list 接口的特点是有序且可以重复
    • set接口的特点是无序且不可重复
    • ArrayList和Linkedlist是list接口的实现类
    • Hashset 和Treeset是set接口的实现类
    • HashMap和TreeMap是Map接口的实现类
    • Collection维护的是单列集合
    • Map是一个双列集合,用于存储具有Key Value映射关系的键值对,使用时可以通过kay找到相应的value值

img

集合的特点

  • 集合是用来存储对象的容器,而对象是用来存放数据的,当对象多了就需要集中式管理

  • 集合是可变长度,大小不固定

数组与集合的区别

  • 数组是不可变的一旦定义不可改变,而集合是可变的

  • 数组可以存储基础数据类型也可以存储引用数据类型,集合只能存储引用数据类型

  • 数组中必须是同一种类型,而集合可以是不同数据类型

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

**List:**一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多
个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。
**Set:**一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一
个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及TreeSet。
Map是一个键值对集合,存储键、值和之间的映射。 Key无序,唯一;value 不要求有序,允许重
复。Map没有继承于Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应
的值对象。
Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap

集合框架底层数据结构

Collection

  1. List

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

    2. Set

    **HashSet(**无序,唯一):基于 HashMap 实现的,底层采用 HashMap 来保存元素
    LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来
    实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不
    过还是有一点点区别的。
    TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)

    Map

    HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是
    主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较
    大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
    **LinkedHashMap:**LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散
    列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加
    了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的
    操作,实现了访问顺序相关逻辑。
    HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突
    而存在的
    TreeMap: 红黑树(自平衡的排序二叉树)

那些集合是线程安全的

  • **Vector:**就比Arraylist多了个 synchronized (线程安全),因为效率较低,现在已经不太建议使
    用。
  • **hashTable:**就比hashMap多了个synchronized (线程安全),不建议使用
  • ConcurrentHashMap: 相当于分割了十六个桶,可以使十六个线程同时访问 ,既保证了准确,有保证了高效性

Java集合的快速失败机制 “fail-fast”?

  • 是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生
    fail-fast 机制。

10. 怎么确保一个集合不能被修改?

可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变
集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常

Collection接口

List接口

迭代器 Iterator 是什么?

  • Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来
    获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允许调用者在迭代过程
    中移除元素。

  • 因为所有Collection接继承了Iterator迭代器

遍历一个 List 有哪些不同的方式?每种方法的实现原理是什么?Java 中 List

遍历的最佳实践是什么?

遍历方式有以下几种:

  1. for 循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,
    当读取到最后一个元素后停止。
  2. 迭代器遍历,Iterator。Iterator 是面向对象的一个设计模式,目的是屏蔽不同数据集合的特
    点,统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。
  3. foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现,使用时不需要显式声明
    Iterator 或计数器。优点是代码简洁,不易出错;缺点是只能做简单的遍历,不能在遍历过
    程中操作数据集合,例如删除、替换

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

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

ArrayList 和 Vector 的区别是什么?

  • 这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合
    线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非
    线程安全的。
  • 性能:ArrayList 在性能方面要优于 Vector。
  • 扩容:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在 Vector 扩容每次
    会增加 1 倍,而 ArrayList 只会增加 50%

List 和 Set 的区别

  • List , Set 都是继承自Collection 接口
  • List 特点:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。
  • Set 特点:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及
    TreeSet。
  • 另外 List 支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。

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

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

Map接口

什么是Hash算法

  • 哈希算法是指把任意长度的二进制映射为固定长度的较小的二进制值,这个较小的二进制值叫做哈希值。

说一下HashMap的实现原理?

HashMap 基于 Hash 算法实现的

  1. 当我们往HashMap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数
    组中的下标
  2. 存储时,如果出现hash值相同的key,此时有两种情况。
    (1)如果key相同,则覆盖原始值;
    (2)如果key不同(出现冲突),则将当前的key-value放入链表中
  3. 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
  4. 理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)

JDK1.7 VS JDK1.8 比较

JDK1.8主要解决或优化了一下问题:

  1. resize 扩容优化
  2. 引入了红黑树,目的是避免单条链表过长而影响查询效率,红黑树算法请参考
  3. 解决了多线程死循环问题,但仍是非线程安全的,多线程时可能会造成数据丢失问题。

什么是哈希冲突?

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

为什么HashMap中String、Integer这样的包装类适合作为K?

  • String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少Hash碰撞的几率
  • 都是final类型,即不可变性,保证key的不可更改性,不会存在获取hash值不同的情况
  • 内部已重写了 equals() 、 hashCode() 等方法,遵守了HashMap内部的规范 ,不容易出现Hash值计算错误的情况;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值