Java集合

本文详细介绍了Java集合框架中的List、Set、Map的区别,包括底层数据结构、快速失败与安全失败机制、Array与ArrayList的区别、Comparable与Comparator的差异,以及Collection与Collections的关系。此外,还对比了ArrayList、LinkedList、HashSet与HashMap的特性,以及HashMap在JDK1.7和1.8版本的变化。
摘要由CSDN通过智能技术生成

作为新手学习java集合的学习笔记,仅为自用,欢迎交流,不喜勿喷哦



前言

本文是对于Java集合一些基础知识点的总结,方便后续的回顾。


1.List,Set,Map三者的区别?

List,Set和Map是常见的集合数据类型。

  1. List :有序集合,可存储重复元素,可存储多个 null 。
  2. Set :无序集合,不可存储重复元素,只能存储一个 null 。
  3. Map:使用键值对的方式对元素进行存储, key 是无序的,且是唯一的。 value 值不唯一。不同
    的 key 值可以对应相同的 value 值。

2.底层数据结构

  1. List:
    ArrayList :数组
    LinkedList :双线链表
  2. Set :
    HashSet :底层基于 HashMap 实现, HashSet 存入读取元素的方式和 HashMap 中的 Key 是
    一致的。
    TreeSet :红黑树
  3. Map :
    HashMap : JDK1.8之前 HashMap 由数组+链表组成的, JDK1.8之后有数组+链表/红黑树组
    成,当链表长度大于8时,链表转化为红黑树,当长度小于6时,从红黑树转化为链表。
    HashTable :数组+链表
    TreeMap :红黑树

3.快速失败机制 “fail-fast”和安全失败机制“fail-safe”是什么?

  1. 快速失败:
    Java的快速失败机制是Java集合框架中的一种错误检测机制,当多个线程同时对集合中的内容进行修改时可能就会抛出 ConcurrentModificationException 异常。其实不仅仅是在多线程状态下,在单线程中用增强 for 循环中一边遍历集合一边修改集合的元素也会抛出ConcurrentModificationException 异常。
  2. 安全失败
    采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会抛出 ConcurrentModificationException 异常。

4.Array 和 ArrayList 有何区别?

  1. Array 可以包含基本类型和对象类型, ArrayList 只能包含对象类型;
  2. Array 大小是固定的, ArrayList 的大小是动态变化的;
  3. ArrayList 有着更多的内置方法,如 addAll() , removeAll() ,Array没有。

5.comparable 和 comparator的区别?

Comparable和Comparator是Java中用于比较对象的两种接口,它们之间有以下区别:

  1. Comparable:

Comparable接口在Java.lang包中定义;
当一个类实现了Comparable接口时,它表明该类的对象是可比较的;
实现Comparable接口的类必须重写compareTo()方法,该方法定义了对象之间的自然排序规则;
自然排序是指类内部定义的默认排序顺序。

  1. Comparator:

Comparator接口在Java.util包中定义;
Comparator接口用于定义不同于对象自身的比较规则;
它允许在不修改对象本身的情况下定义多种比较方式;
实现Comparator接口的类必须重写compare()方法,该方法定义了两个对象之间的比较规则;
Comparator对象可以用于对集合中的元素进行排序。

6.Collection 和 Collections 有什么区别?

  1. Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。
  2. Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法,例如常用的 sort()
    方法。此类不能实例化,就像一个工具类,服务于Java的 Collection 框架。

7.List集合

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

  1. 普通for 循环遍历:遍历者自己在集合外部维护一个计数器,依次读取每一个位置的元素。
  2. Iterator 遍历:基于顺序存储集合的 Iterator 可以直接按位置访问数据。基于链式存储集合的
    Iterator ,需要保存当前遍历的位置,然后根据当前位置来向前或者向后移动指针。
  3. foreach 遍历: foreach 内部也是采用了 Iterator 的方式实现,但使用时不需要显示地声明
    Iterator 。

ArrayList的扩容机制

ArrayList 的初始容量为10,扩容时对是旧的容量值加上旧的容量数值进行右移一位(位运算,相当于除以2,位运算的效率更高),所以每次扩容都是旧的容量的1.5倍。

ArrayList、Vector、LinkedList的区别

  1. 线程安全性:

ArrayList是非线程安全的,不同线程同时访问ArrayList可能导致不确定的结果。
Vector是线程安全的,它的方法都是同步的,多个线程可以安全地同时访问Vector。
LinkedList也是非线程安全的,和ArrayList类似,它不具备同步措施。

  1. 性能:

ArrayList的内部实现是基于数组的动态数组,因此在随机访问时性能较好,但在插入和删除元素时,由于需要移动元素位置,性能较差。
Vector在很大程度上与ArrayList相似,但由于它是线程安全的,因此在并发访问时性能通常较差。
LinkedList的内部实现是基于双向链表,因此在插入和删除元素时性能较好,但在随机访问时性能较差。

  1. 扩容机制:

ArrayList和Vector都使用了动态数组实现,当数组空间不足时会自动扩容。ArrayList默认情况下每次扩容为原来的1.5倍,而Vector默认情况下每次扩容为原来的2倍。
LinkedList的存储空间由节点组成,不需要像动态数组那样扩容,因为每次添加元素时都会创建一个新的节点。

  1. 迭代器性能:

在使用迭代器进行遍历时,ArrayList的性能通常优于LinkedList。这是因为ArrayList内部是基于数组的,可以通过索引快速访问元素;而LinkedList需要按照节点顺序一个一个地遍历。

8.Set集合

HashSet与HashMap的区别

HashMapHashSet
实现了 Map 接口实现了 Set 接口
存储键值对存储对象
key 唯一, value 不唯一存储对象唯一
HashMap 使用键( Key )计算 HashcodeHashSet 使用成员对象来计算 hashcode 值
速度相对较快速度相对较慢

9.Map集合

HashMap在JDK1.7和JDK1.8中的区别

JDK1.7JDK1.8
底层结构数组+链表数组+链表/红黑树(链表大于8)
hash值计算方式9次扰动 = 4次位运算 + 5次异或运算2次扰动 = 1次位运算 + 1次异或运算
插入数据方式头插法尾插法
扩容后存储位置的计算方式重新进行hash计算原位置或原位置+旧容量

HashMap、ConcurrentHashMap及Hashtable 的区别

HashMap(JDK1.8)ConcurrentHashMap(JDK1.8)Hashtable
底层实现数组+链表/红黑树数组+链表/红黑树数组+链表
线程安全不安全安全( Synchronized 修饰Node节点)安全( Synchronized 修饰整个表)
效率较高
扩容初始16,每次扩容成2n初始16,每次扩容成2n初始11,每次扩容成2n+1
是否支持Null key和Null Value可以有一个Null key,Null Value多个不支持不支持

总结

以上就是今天要讲的内容,本文仅仅简单介绍了Java集合的一些基础知识,后续还需要不断地深入探索。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值