JavaSE(13)——Java集合总结

java集合总结

1. 概述

java容器可分为两大类

  • Collection
    • List
      • ArrayList
      • LinkedList
      • Vector (了解即可,已过时)
    • Set
      • TreeSet
      • HashSet
        • LinkedHashSet
    • Map
      • HashMap
        • LinkedHashMap
      • TreeMap
      • ConcurrentHashMap
      • HashTable (了解即可,已过时)

2. ArrayList和Vector的区别

共同点

  • 这两个类都实现了List接口
  • 都是有序的集合,底层是数组
  • 可以按位置索引号取出某个元素
  • 允许元素重复和为null

区别

  • 同步性
    • ArrayList是非同步的
    • Vector是同步的
    • 即使需要同步的时候,可以使用Collections工具类来构建出同步的ArrayList而不用Vector
  • 扩容大小
    • Vector增长到原来的2倍,ArrayList增长到原来的1.5倍

3. HashMap和HashTable的区别

共同点

  • 从存储结构和实现来讲,基本上都是相同的,都是实现Map接口

区别

  • 同步性
    • HashMap是非同步的
    • HashTable是同步的
    • 需要同步的时候,一般不使用HashTable,而使用ConcurrentHashMap
  • 是否允许为null
    • HashMap允许为null
    • HashTable不允许为null
  • contains方法
    • HashTable有contains方法
    • HashMap把HashTable中的contains方法替换成了containsValue和ContainsKey方法
  • 继承不同
    • HashMap extends AbstractMap
    • HashTable extends Dictionary

4. List和Map的区别

共同点

  • 都是Java常用的容器,都是接口

区别

  • 存储结构不同
    • List是存储单列的集合
    • Map存储的是Key-Value键值对的集合
  • 元素是否可重复
    • List允许元素重复
    • Map不允许Key重复
  • 是否有序
    • List集合是有序的
    • Map集合是无序的

5. 常见问题

5.1 Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用 == 还是equals?

​ Set集合大都使用的是Map集合的put方法来添加元素

​ 以HashSet为例,HashSet里的元素不能重复,在源码 (HashMap) 是这样体现的:

// 1. 如果key 相等  
if (p.hash == hash &&
    ((k = p.key) == key || (key != null && key.equals(k))))
    e = p;
// 2. 修改对应的value
if (e != null) { // existing mapping for key
    V oldValue = e.value;
    if (!onlyIfAbsent || oldValue == null)
        e.value = value;
    afterNodeAccess(e);
    return oldValue;
}

​ 添加元素的时候,如果key (也对应的Set集合的元素)相等,那么则修改value值。而在Set集合中,value值仅仅是一个Object对象 (该对象对Set集合而言是没有用的)。

​ 因此,Set集合如果添加的元素相同时,是根本没有插入的 (仅修改了一个无用的value值),从源码 (HashMap) 中也看出来, == 和equals方法都有使用。

5.2 Collection和Collections的区别

  1. Collection是集合的上层接口,继承它的有Set和List接口
  2. Collections是集合的工具类,提供了一系列的静态方法对集合的搜索、查找、同步等操作

5.3 ArrayList,LinkedList的存储性能和特性

ArrayList底层是数组,LinkedList底层是双向链表。

  • ArrayList支持以下标位置进行索引出对应的元素 (随机访问) ,而LinkedList则需要遍历整个链表来获取对应的元素。因此,一般来说,ArrayList的访问速度是要比LinkedList快的

  • ArrayList由于是数组,对于删除和修改而言消耗是比较大的 (复制和移动数组实现) ;LinkedList是双向链表,删除和修改只需要修改对应的指针即可,消耗是很小的。因此,一般来说LinkedList的增删速度是要比ArrayList要快的

  • 特殊情况下,当数据量达百万级别时,在list的末尾进行增删操作ArrayList是要比LinkedList快的。而在list的中间进行删除操作时,由于LinkedList的遍历耗时要比ArrayList的复制移动多,因此,还是ArrayList要快。

5.4 Enumeration和Iterator接口的区别

与Enumeration相比,Iterator更加安全,因为当一个集合正在被遍历的时候,它会阻止其他线程去修改集合。

  • 迭代时,经常会抛出ConcurrentModificationException异常,说明迭代的时候还在修改元素。
  • 这其实是fail-fast机制
  • 关于fail-fast机制的解释:https://blog.csdn.net/panweiwei1994/article/details/77051261

区别:

  • Iterator的方法名比Enumeration更科学
  • Iterator有fail-fast机制,比Enumeration更安全
  • Iterator能够删除元素,Enumeration并不能删除元素

5.5 ListIterator的特点

  • ListIterator继承了Iterator接口,它用于遍历List集合的元素。
  • ListIterator可以实现双向遍历,添加元素,设置元素。
public interface ListIterator<E> extends Iterator<E> {
    boolean hasNext();
    E next();
    boolean hasPrevious();
    E previous();
    int nextIndex();
    int previousIndex();
    void remove();
    void set(E e);
    void add(E e);
}

5.6 并发集合类

java1.5并发包 (java.util.concurrent) 包含线程安全集合类,允许在迭代时修改集合。

  • 迭代器被设计为fail-fast的,会抛出ConcurrentModificationException
  • 一部分类为:
    • CopyOnWriteArrayList
    • ConcurrentHashMap
    • CopyOnWriteArraySet

5.7 HashMap的key值是类对象

当HashMap的key值是类对象时,需要同时重写该类的hashCode ()方法和它的equals方法。

  • 从源码可知,在插入元素的时候是先算出该对象的hashCode。如果hashCode相等的话,那么表明该对象是存储在同一位置上的。
  • 如果调用equals方法,两个key相同,则替换元素
  • 如果调用equals方法,两个key不相同,则说明该hashCode仅仅是碰巧相同,属于哈希碰撞。将新增的元素放在桶的链表上

一般来说,我们会认为,只要两个对象的成员变量的值是相等的,那么就认为这两个对象是相等的。因为,Object底层比较的是两个对象的地址,而对开发而言,这样的意义不大,因此需要重写equals方法

重写了equals方法,就需要重写hashCode方法。因为equals认定了这两个对象相同,而同一个对象调用hashCode方法时,返回的是相同的值的。

5.8 Java集合框架的选择

  1. 根据需要确定集合的类型。如果是单列的集合,考虑使用Collection下的子接口ArrayListSet。如果是映射,则考虑使用Map
  2. 确定集合类型之后,需要确定使用该集合的哪个子类
    • Tree红黑树类型
    • Linked双向链表类型
    • 线程安全类型
    • 是否需要同步
    • 迭代时是否需要有序
    • 是否需要排序
  3. 估算存放集合的数据量有多大,无论是List还是Map,实现动态增长时都是很消耗性能的。在初始化集合的时候给出一个合理的容量会减少动态增长时的消耗
  4. 使用泛型,避免在运行时出现ClassCastException
  5. 尽可能使用Collections工具类,或者获取只读、同步或空的集合,而非编写自己的实现。它会提供代码的重用性,有更好的稳定性和可维护性。

5.9 ArrayList集合加入10万条数据时,应该如何提高效率

  • ArrayList的默认初始容量为10,而插入大量数据的时候需要不断扩容,扩容是非常影响性能的。因此,在明确需要插入10万条数据时,可以直接在初始化时设置ArrayList的容量。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值