这篇笔记对几个常用的集合实现,从效率,线程安全和应用场景进行综合比较。

1.ArrayList、LinkedList与Vector的对比

(1)相同和不同
都实现了List接口,使用类似。
Vector和ArrayList的底层实现都是数组,这一点与LinkedList的双向链表不同。
Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%。
(2)线程安全
ArrayList、LinkedList都没有进行同步,可以使用 Collections的同步方法进行包装。

(3)性能比较
在ArrayList和Vector中,从一个指定的位置(通过索引)查找数据或是在集合的末尾增加、移除一个元素所花费的时间是一样的,这个时间我们用O(1)表示。但是,如果在集合的其他位置增加或移除元素那么花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除元素的索引位置,即时间复杂度O(N)。为什么会这样呢?因为数组在内存上是连续的,进行上述操作的时候集合中第i和第i个元素之后的所有元素都要执行位移的操作。
如果你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是其他操作,你最好选择其他的集合操作类。比如,LinkList集合类在增加或移除集合中任何位置的元素所花费的时间都是一样的O(1),但它在索引一个元素的是有比较慢,O(i),其中i是索引的位置。

2.HashMap与HashTable比较

(1)是否允许空值
HashMap允许 null 值(key和value都可以),Hashtable不允许 null 值(key 和 value 都不可以),
这一点在之前学习源码时也注意到了,看一下HashTable的源码:

1
2
3
4
5
6
7
public synchronized V put(K key, V value) {
       // Make sure the value is not null
       if (value == null) {
           throw new NullPointerException();
       }
       ......
   }

(2)哈希值的使用不同
Hashtable直接使用对象的hashCode,代码是这样的:

1
2
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;

而HashMap重新计算hash值,这一点在之前的分析中也看到了:

1
2
int hash = hash(k);
int i = indexFor(hash, table.length);

另外还有一些如内部链表数组使用方式不同等差异。

(3)线程安全
HashMap和HashTable在线程安全性上就如同ArrayList和Vector类似,
HashTable的操作都使用synchronized做了同步。需要注意这是一种性能较低的线程安全。

>>HashSet和HashMap的区别

HashSet 实现了 Set 接口,它不允许集合中有重复的值,在将对象存储在 HashSet 之前,要先确保对象重写 equals()和 hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。
HashMap 实现了 Map 接口,Map 接口对键值对进行映射。Map 中不允许重复的键。Map 接口有两个基本的实现,HashMap 和 TreeMap。TreeMap 保存了对象的排列次序,而 HashMap 则不能。HashMap 允许键和值为 null。

(1)不同之处
HashMap实现了Map接口 HashSet实现了Set接口
HashMap储存键值对 HashSet仅仅存储对象
使用put()方法将元素放入map中 使用add()方法将元素放入set中
HashMap中使用键对象来计算hashcode值 HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false
HashMap比较快,因为是使用唯一的键来获取对象 HashSet较HashMap来说比较慢

(2)线程安全
HashMap 是非 synchronized 的。

Java集合源码学习(五)几种常用集合类的比较相关推荐

  1. Java集合源码学习(四)HashMap

    一.数组.链表和哈希表结构 数据结构中有数组和链表来实现对数据的存储,这两者有不同的应用场景, 数组的特点是:寻址容易,插入和删除困难:链表的特点是:寻址困难,插入和删除容易: 哈希表的实现结合了这两 ...

  2. Java集合源码学习(4)HashSet

    1 概述 HashSet 是一个没有重复元素的集合.它的底层是由HashMap实现的,不保证元素的顺序.HashSet允许使用 null 元素. 截取一段源码: public class HashSe ...

  3. Java集合源码分析(二)ArrayList

    ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...

  4. JAVA JDK 源码学习

    JAVA JDK 源码学习 ,以1.8为例,按照下面图片顺序依次学习: applet ,awt,beans,io,lang,math,net,nio,rmi,security,sql,text,tim ...

  5. java遍历范型list_Java 集合(1)-- 俯瞰 Java 集合源码以及分类

    (一) java集合分类 之前大概分为三种,Set,List,Map三种,JDK5之后,增加Queue.主要由Collection和Map两个接口衍生出来,同时Collection接口继承Iterab ...

  6. Java集合源码浅析(一) : ArrayList

    (尊重劳动成果,转载请注明出处:https://yangwenqiang.blog.csdn.net/article/details/105418475冷血之心的博客) 背景 一直都有这么一个打算,那 ...

  7. java Integer 源码学习

    转载自http://www.hollischuang.com/archives/1058 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的 ...

  8. 【开源与项目实战:开源实战】77 | 开源实战一(下):通过剖析Java JDK源码学习灵活应用设计模式

    上一节课,我们讲解了工厂模式.建造者模式.装饰器模式.适配器模式在 Java JDK 中的应用,其中,Calendar 类用到了工厂模式和建造者模式,Collections 类用到了装饰器模式.适配器 ...

  9. 转:【Java集合源码剖析】LinkedHashmap源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/37867985   前言:有网友建议分析下LinkedHashMap的源码,于是花了一晚上时 ...

最新文章

  1. 2022-2028年中国商业综合体行业市场前瞻与投资规划分析报告
  2. c++ to_string用法
  3. 一键生成CSDN文章的思维导图目录
  4. 极限中0除以常数_高中物理必知的50个关键常数
  5. 持续5个月,200+笔记,3千多人参与,邀请你来学源码~
  6. 算法导论-VLSI芯片测试问题
  7. 第三篇:稳定性之借风险之力驱动架构演进
  8. 隐藏a标签seo_SEO网站优化,新手SEO常犯的五个错误!
  9. 专升本c语言名词解释题_福建普通高校专升本各类别考试题型及分值
  10. Apache的多处理模块MPM
  11. HTML5 —— 属性
  12. I学霸官方免费教程二十八:Java排序算法之选择排序和冒泡排序
  13. 包邮送72本R语言和Python的书籍
  14. win7 ie11版本安装报此更新不适用于计算机问题
  15. springboot毕设项目超市仓库管理系统15g4i(java+VUE+Mybatis+Maven+Mysql)
  16. 对PID的理解及其实现公式
  17. debian下配置防火墙iptables
  18. Java序列化与注解面试题
  19. 客户期望,客户满意度,客户体验和客户忠诚度之间存在的联系
  20. 【设计模式】模板模式——jdbc案例

热门文章

  1. c语言enum能自定义吗,18、C语言 —— 枚举enum
  2. centos7.3修改mysql密码_Centos7.3下mysql5.7.18安装并修改初始密码的方法
  3. MAC下载Linux Centos镜像文件
  4. js for循环 ajax
  5. 3ds Max绘制青花瓷茶壶
  6. java基础进阶一:String源码和String常量池
  7. 控制台输入与Math Random的基本使用
  8. C#在后台运行操作:BackgroundWorker的用法
  9. python 错误--UnboundLocalError: local variable '**' referenced before assignment
  10. 第22节 三个败家子(22)——霸王无敌