Java 中map和list

img

map和list

1、List(有序、可重复)
List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

2、Set(无序、不能重复)
Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

3、Map(键值对、键唯一、值不唯一)
Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。

是否有序 是否允许重复
Collection
List Y Y
Set AbstractSet No NO
HashSet No NO
TreeSet Y(使用二叉排序树) NO
Map AbstractMap NO Key唯一,Value可重复
HashMap NO Key唯一,Value可重复
TreeMap Y(二叉排序树) Key唯一,Value可重复
List实现类:

Vector和ArrayList

  1. vector是线程安全 的, arraylist 是线程不安全的。Vector 由于使用了 synchronized
    方法(线程安全)所以性能上比 ArrayList 要差
  2. 如果集合中的元素的数目大于目前集合数组的长度时,vector 容量2,而
    arraylist容量
    1.5。如果在集合中使用数据量比较大的数据,用 vector 有一定的优势。
  3. ArrayList 和 Vector是采用数组方式存储数据,都是通过索引访问数据,如果移动一个指定位置都会导致后面的元素都发生移动。索引数据快,插入数据慢。

ArrayList和LinkedList

  1. ArrayList 是实现了基于动态数组的数据结构,LinkedList 基于链表的数据结构。
  2. 对于随机访问 get,ArrayList 优于 LinkedList,因为 LinkedList 要移动指针。
  3. 对于新增和删除操作 add 和 remove,LinedList 比较占优势,因为 ArrayList 要移动数据。这一点要看实际情况的。若只对单条数据插入或删除,ArrayList 的速度反而优于 LinkedList。但若是批量随机的插入删除数据,LinkedList 的速度大大优于 ArrayList.
Map实现类
  • HashMap

见博客:https://blog.csdn.net/weixin_43887870/article/details/107641340

现在讨论HashMap的线程安全性。

Hash Map线程是不安全的,为了保证线程安全可以使用

  • 1、HashTable

hashTable 就是在HashMap每个方法上添加synchronized关键字。不会出现两个线程同时对数据进行操作的情况,因此保证了线程安全性,但是也大大的降低了执行效率。因此是不推荐的。

  • 2、ConcurrentHashMap

    ConcurrentHashMap是HashMap的线程安全版本,相对 HashMap 和 Hashtable, ConcurrentHashMap 增加了 Segment 层,每个 Segment 原理上等同于一个 Hashtable, ConcurrentHashMap 为 Segment 的数组。

ConcurrentHashMap使用的是分段锁技术,将ConcurrentHashMap将锁一段一段的存储,然后给每一段数据配一把锁(segment),当一个线程占用一把锁(segment)访问其中一段数据的时候,其他段的数据也能被其它的线程访问,默认分配16个segment。默认比Hashtable效率提高16倍。

Java 中map和list_第1张图片

注:hashmap的key和value可以为null,但是concurrentHashMap的key和value不能为null。

ConcurrentHashMap 在 jdk1.7 的升级到 1.8 中的变化

Java 中map和list_第2张图片

  • 改进一:取消 segments 字段,直接采用 transient volatile HashEntry[] table 保存数据,,synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,锁的粒度从多个 Node 级别又减小到一个 Node 级别,再度减小锁竞争,减小程序同步的部分。
  • 改进二:将原先 table 数组+单向链表的数据结构,变更为 table 数组+单向链表+红黑树的结构。

HashMap与HashTable区别

  1. 继承类不同,hashtable继承自字典,而hashmap继承自抽象类abstractmap.
  2. HashTable中key和Value都不能为null,**在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个valu为 null 。**所以不能使用get()方法判断HashMap中是否存在改键,必须使用containsKey()。
  3. 哈希值的使用不同,HashTable 直接使用对象的 hashCode。而 HashMap 重新计算 hash 值,使用扰动函数进行计算,计算方式:hashcode 值先右移 16 位,再与 hashcode 值进行异或操作。 得到值在与长度-1进行与运算。使用扰动函数的原因是:减少碰撞,降低hash冲突的几率
  4. Hashtable 和 HashMap 它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable 中 hash 数组默认大小是 11,增加的方式是 old*2+1。HashMap 中 hash 数组的默认大小是 16,而且一定是 2 的指数。

你可能感兴趣的:(Java,java)