java集合

1.接口继承关系和实现

集合类存放与java.util包中,主要有三种集合:set、list(包含Queue)和map。

  1. Collection:Collection接口是List、Set、Queue的基础接口。
  2. Iterator:迭代器,可以通过迭代器访问和修改集合中的数据。
  3. Map:是影射表的基础接口。
    在这里插入图片描述
    集合框架:
  • Collection:
    • List:
      • ArrayList:
        • 底层是数组实现,查询快增删慢。
        • 线程不安全。
        • 扩容时size*1.5+1。
        • 排列有序元素可以重复。
      • LinkedList:
        • 底层实现为链表,增删快查询慢。
        • 线程不安全。
        • 排列有序,元素可以重复。
        • 因为底层是双向链表所以没有容量也不需要扩容。
      • Vector:
        • 线程安全。
        • 底层使用数组,查询快增删慢。
        • 扩容时size*2
    • Set:
      • HashSet:
        • 线程不安全。
        • 元素不可以重复,无序。
        • 底层使用hash表实现。
        • 内部是HashMap。
      • LinkedHashSet:
        • 采用hash表实现,并采用双向链表记录插入顺序。
        • 内部是linkedHashMap实现
      • TreeSet:
        • 排列无序,不可重复
        • 底层使用二叉树实现
        • 内部是TreeMap或SortedSet。
    • Queue: 在两端出入的list,所以也可以使用链表或数组实现。
  • Map:
    • HashMap:
      • key不能重复,但是可以为空。
      • 底层实现为hash表。
      • 线程不安全
    • TreeMap:
      • 键不可以重复,值可以重复
      • 底层二叉树
      • 线程不安全
    • HashTable:
      • 线程安全。
      • 底层使用hash表实现。
      • key和value都不允许为空。

2.List

java中List一共有三个实现类,ArrayList、LinkedList、Vector。

  • ArrayList:是最常用的list集合,底层使用数组实现。所以可以对元素实现快速的随机访问,但是对元素进行移动(插入、删除)时比较耗时。因为数组有大小容量且容量是固定的,所以当ArrayList需要扩容的时候,需要重新创建一个数组然后将当前数组元素复制到新的数组中。所以ArrayList适合进行随机查找或遍历,不适合频繁插入和删除。
  • LinedList:LinkedList的底层是由双向链表实现的,所以天然适合元素的插入和删除操作。但是随机访问速度就会慢一些。另外它扩展了List中没有定义的方法,可以在头部和尾部进行插入和删除元素。所以它还可以当做栈和队列以及双向队列使用。
  • Vector:通过数组实现不过方法都加了同步锁,所以是线程安全的。但是效率很低一般不会使用。

3.Set

Set最重要的属性就是元素不可重复。元素是否重复的判断标准就是对象的hashCode和equals方法是否返回true。如果想让两个不同的对象视为相等的就必须覆盖Object的hashCode和equals方法。

  • HashSet(hash表):哈希表存放的是哈希值。hashSet存储元素并不是按照插入顺序保存的,而是按照元素的hash值获取的。判断两个元素是否相等会先判断hashCode是否相等,如果hashCode相等则进一步比较equals方法是否返回true。如果返回true则表示是同一个对象则拒绝插入。如果仅hashCode相等,equals方法返回false则在同一个位置维护一个链表(hash桶)来存储同一位置的元素。

在这里插入图片描述

  • TreeSet:
    1. TreeSet是使用二叉树的原理对新增加的节点按照指定的顺序排序(升序或降序),每增加一个元素都要进行一次排序。
    2. Integer和String对象都可以直接进行排序,也就是直接添加到TreeSet中。其他自定义类型则需要实现Comparable接口,并重写compareTo函数,才可以正常使用。
    3. LinkedHashSet:(HashSet + LinkedHashMap)
      对于 LinkedHashSet 而言,它继承与 HashSet、又基于 LinkedHashMap 来实现的LinkedHashSet 底层使用 LinkedHashMap 来保存所有元素,它继承与 HashSet,其所有的方法操作上又与 HashSet 相同,因此 LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,底层构造一个 LinkedHashMap 来实现,在相关操作上与父类 HashSet 的操作相同,直接调用父类 HashSet 的方法即可。

3.Map

Map是key-value形式的键值对存储。

3.1HashMap(数组+链表+红黑树)

HashMap根据hashCode值存取数据,大部分情况下可以通过key直接定位到值,也就是随机查询效率为O(1)。但是遍历速度却不确定,HashMap允许key值为null但是key值不能重复。
HashMap是线程非安全的,多个线程并发写HashMap会产生线程安全问题。
线程安全的HashMap有synchronizedMap或者并发包下的ConcurrentHashMap。

3.1.1 JDK1.7中HashMap的实现

在这里插入图片描述
HashMap底层是一个链表组成的数组,链表的元素是Entry,包含四个属性key、value、next、hash。其中next指向下一个元素。多个元素构成了单向链表。
HashMap主要属性:

  1. capacity:当前数组的容量,始终爆出2^n,可以扩容,扩容后大小为当前数组的两倍。
  2. loadFactor:加载因子,默认值为0.75。
  3. threshold:扩容阈值= capacity*loadFactor。
3.1.2 JDK1.8实现

在这里插入图片描述
java8对HashMap的改造最主要的就是在原来数组+链表的结构上增加了红黑树。当链表元素超过8个后就会转为红黑树存储hash值相同的元素。这样相同位置的查找效率从原来的O(n)变为O(logN)。

4.ConcurrentHashMap

4.1Segment段

ConcurrentHashMap和HashMap思路是一样的,但是它支持并发操作。支持并发操作的原因就是它是由一个个Segment组成的。
Segment是线程安全的,因为Segment继承自ReentrantLock,每次操作Segment时都会通过ReentrantLock来加锁这样每个Segment都是线程安全的,也就保证了整个ConcurrentHashMap是线程安全的。
每个ConcurerentHashMap默认由16个Segment组成。这个值在初始化是可以手动修改,但是一旦初始化后就不能再修改。
JDK1.7实现:
在这里插入图片描述
JDK1.8实现:

在这里插入图片描述

4.2HashTable

Hashtable 是遗留类,很多映射的常用功能与 HashMap 类似,不同的是它承自 Dictionary 类,并且是线程安全的,任一时间只有一个线程能写 Hashtable,并发性不如 ConcurrentHashMap,因为 ConcurrentHashMap 引入了分段锁。Hashtable 不建议在新代码中使用,不需要线程安全的场合可以用 HashMap 替换,需要线程安全的场合可以用 ConcurrentHashMap 替换。

4.3TreeMap

TreeMap 实现 SortedMap 接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时,得到的记录是排过序的。如果使用排序的映射,建议使用 TreeMap。在使用 TreeMap 时,key 必须实现 Comparable 接口或者在构造 TreeMap 传入自定义的Comparator,否则会在运行时抛出 java.lang.ClassCastException 类型的异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值