八股之Java集合

Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于Collection 接口,下面又有三个主要的子接口:ListSetQueue

  • List: 存储的元素有序、可重复
  • Set: 存储的元素不可重复
  • Queue: 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。
  • Map: 使用键值对存储,key 无序、不可重复,value 无序、可重复

Java 集合提高了数据的存储和处理的灵活性,可以更好地适应现代软件开发中多样化的数据需求,并支持高质量的代码编写

一、List

1.ArrayList

(1)ArrayList 和 Array 的区别

ArrayList 内部基于动态数组实现,比 Array(静态数组) 更加灵活:

  • ArrayList会动态地扩容或缩容
  • ArrayList 允许使用泛型来确保类型安全,Array 不可以
  • ArrayList 中只能存储对象。对于基本类型数据,需要使用对应的包装类。Array 可以直接存储基本类型数据,也可以存储对象
  • ArrayList 支持插入、删除、遍历等常见操作,并且提供了丰富的 API 操作
  • ArrayList创建时不需要指定大小,而Array创建时必须指定大小
// 初始化一个 String 类型的 ArrayList
 ArrayList<String> stringList = new ArrayList<>(Arrays.asList("hello", "world", "!"));
// 添加元素到 ArrayList 中
 stringList.add("goodbye");
 System.out.println(stringList);// [hello, world, !, goodbye]
 // 修改 ArrayList 中的元素
 stringList.set(0, "hi");
 System.out.println(stringList);// [hi, world, !, goodbye]
 // 删除 ArrayList 中的元素
 stringList.remove(0);
 System.out.println(stringList); // [world, !, goodbye]

(2)ArrayList 可以添加 null 值吗?

可以但不建议, null 值无意义,会让代码难以维护(比如忘记做判空处理就会导致空指针异常)

ArrayList<String> listOfStrings = new ArrayList<>();
listOfStrings.add(null);
listOfStrings.add("java");
System.out.println(listOfStrings);  // [null, "java"]

(3)ArrayList 扩容机制

2.LinkedList

3.ArrayList 与 LinkedList 区别?

  • 是否保证线程安全: ArrayListLinkedList 都不同步的,不保证线程安全
  • 底层数据结构: ArrayList 底层使用的是 Object 数组LinkedList 底层使用的是 双向链表 数据结构
  • 是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而 ArrayList(实现了 RandomAccess 接口) 支持快速随机访问(get(int index))
  • 内存空间占用: ArrayList 的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗更多空间

项目中一般不会使用 LinkedList ,几乎都可以用 ArrayList 来代替,并且性能通常会更好!

二、Set

三、Queue

四、Map

1.HashMap

(1)HashMap 和 Hashtable 的区别

  • 线程是否安全: HashMap 非线程安全的,Hashtable 线程安全的(内部的方法基本都经过synchronized 修饰)(保证线程安全使用 ConcurrentHashMap
  • 效率: 因为线程安全的问题,HashMap 要比 Hashtable 效率高一点。另外,Hashtable 基本被淘汰,不要在代码中使用它
  • 对 Null key 和 Null value 的支持: HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个;Hashtable 不允许有 null 键和 null 值,否则会抛出 NullPointerException
  • 初始容量大小和每次扩充容量大小的不同: ① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小(HashMap 中的tableSizeFor()方法保证 HashMap 总是使用 2 的幂作为哈希表的大小)
  • 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间(后文中我会结合源码对这一过程进行分析)。Hashtable 没有这样的机制。
  • 哈希函数的实现HashMap 对哈希值进行了高位和低位的混合扰动处理以减少冲突,而 Hashtable 直接使用键的 hashCode() 值。

(2)HashMap 和 HashSet的区别

HashSet 底层是基于 HashMap 实现的

HashMapHashSet
实现了 Map 接口实现 Set 接口
存储键值对仅存储对象
调用 put()向 map 中添加元素调用 add()方法向 Set 中添加元素
HashMap 使用键(Key)计算 hashcodeHashSet 使用成员对象来计算 hashcode 值,对于两个对象来说 hashcode 可能相同,所以equals()方法用来判断对象的相等性

(3)HashMap 和 TreeMap 区别

(4)HashSet 如何检查重复?

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值