[转]Java五个最常用的集合类之间的区别和联系
Map<String, ?>只能是只读模式,不能增加,因为增加的时候不知道该写入什么类型的值;
Map<String, Object>可以读和写,只要是所有Object类的子类都可以。
常用的集合类有一下几种:
List结构的集合类:ArrayList类,LinkedList类,Vector类,Stack类
Map结构的集合类:HashMap类,Hashtable类
Set结构的集合类:HashSet类,TreeSet类
Queue结构的集合:Queue接口
HashMap和Hashtable的区别:
HashMap和Hashtable都是java的集合类,都可以用来存放java对象,这是他们的相同点
以下是他们的区别:
1.历史原因:
Hashtable是基于陈旧的Dictionary类的,HashMap是java 1.2引进的Map接口的一个现实。
2.同步性:
Hashtable是同步的,这个类中的一些方法保证了Hashtable中的对象是线程安全的,而HashMap则是异步的,因此HashMap中的对象并不是线程安全的,因为同步的要求会影响执行的效率,所以如果你不需要线程安全的结合那么使用HashMap是一个很好的选择,这样可以避免由于同步带来的不必要的性能开销,从而提高效率,我们一般所编写的程序都是异步的,但如果是服务器端的代码除外。
3.值:
HashMap可以让你将空值作为一个表的条目的key或value
Hashtable是不能放入空值(null)的
ArrayList和Vector的区别:
ArrayList与Vector都是java的集合类,都是用来存放java对象,这是他们的相同点,
区别:
1.同步性:
Vector是同步的,这个类的一些方法保证了Vector中的对象的线程安全的,而ArrayList则是异步的,因此ArrayList中的对象并不 是线程安全的,因为同步要求会影响执行的效率,所以你不需要线程安全的集合那么使用ArrayList是一个很好的选择,这样可以避免由于同步带来的不必 要的性能开销。
2.数据增长:
从内部实现的机制来讲,ArrayList和Vector都是使用数组(Array)来控制集合中的对象,当你向两种类型中增加元素的时候,如果元素的数目超过了内部数组目前的长度他们都需要扩展内部数组的长度,Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,所以最后你获得的这个集合所占的空间总是比你实际需要的要大,所以如果你要在集合中保存大量的数据,那么使用Vector有一些优势,因为你可以通过设置集合的初始大小来避免不必要的资源开销。
总结:
1)如果要求线程安全,使用Vector,Hashtable
2)如果不要求线程安全,使用ArrayList,LinkedList,HashMap
3)如果要求键值对,则使用HashMap,Hashtable
4)如果数据量很大,又要求线程安全考虑Vector
1.ArrayList: 元素单个,效率高,多用于查询
2.Vector: 元素单个,线程安全,多用于查询
3.LinkedList:元素单个,多用于插入和删除
4.HashMap: 元素成对,元素可为空
5.HashTable: 元素成对,线程安全,元素不可为空
ArrayList
底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。
LinkedList
经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。
队列:先进先出的数据结构。
栈:后进先出的数据结构。
注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。
Vector
(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。
面试经验(知识点):
java.util.stack(stack即为堆栈)的父类为Vector。可是stack的父类是最不应该为Vector的。因为Vector的底层是数组,且Vector有get方法(意味着它可能访问到并不属于最后一个位置元素的其他元素,很不安全)。
对于堆栈和队列只能用push类和get类。
Stack类以后不要轻易使用。
实现栈一定要用LinkedList。
(在JAVA1.5中,collection有queue来实现队列。)
Set-HashSet实现类:
遍历一个Set的方法只有一个:迭代器(interator)。
HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复。
在Object中除了有finalize(),toString(),equals(),还有hashCode()。
HashSet底层用的也是数组。
当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode:
int hc=o.hashCode(); 返回的hashCode为整数值。
Int I=hc%n;(n为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n为6为例,如果I=0则放在数组a[0]位置,如果I=1,则 放在数组a[1]位置。如果equals()返回的值为true,则说明数据重复。如果equals()返回的值为false,则再找其他的位置进行比 较。这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode不同。
如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。
在实例中,定义student对象时覆盖它的hashcode。
因为String类是自动覆盖的,所以当比较String类的对象的时候,就不会出现有两个相同的string对象的情况。
现在,在大部分的JDK中,都已经要求覆盖了hashCode。
结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True。
如果偷懒,没有设定equals(),就会造成返回hashCode虽然结果相同,但在程序执行的过程中会多次地调用equals(),从而影响程序执行的效率。
我们要保证相同对象的返回的hashCode一定相同,也要保证不相同的对象的hashCode尽可能不同(因为数组的边界性,hashCode还是可能相同的)。
例子:
public int hashCode(){
return name.hashcode()+age;
}
这个例子保证了相同姓名和年龄的记录返回的hashCode是相同的。
使用hashSet的优点:
hashSet的底层是数组,其查询效率非常高。而且在增加和删除的时候由于运用的hashCode的比较开确定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因为hashSet查询和删除和增加元素的效率都非常高。
但是hashSet增删的高效率是通过花费大量的空间换来的:因为空间越大,取余数相同的情况就越小。HashSet这种算法会建立许多无用的空间。
使用hashSet类时要注意,如果发生冲突,就会出现遍历整个数组的情况,这样就使得效率非常的低。
[转]Java五个最常用的集合类之间的区别和联系的更多相关文章
- 列举两种不同类型的Java标识注释,并解释它们之间的区别。
列举两种不同类型的Java标识注释,并解释它们之间的区别.
- Java Web开发和Python Web开发之间的区别
今天的文章讨论了Java Web开发和Python Web开发之间的区别.我不鼓励我们在这里从Java Web迁移到Python Web开发.我只是想谈谈我的感受.它不一定适合所有情况,仅供我们参考. ...
- Java中Scanner类和BufferReader类之间的区别
java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串.它本质上是使用正则表达式去读取不同的数据类型. Java.io.BufferedReader类为了能够高效的 ...
- java中静态代理跟动态代理之间的区别
文章转载于:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另 ...
- 转:Java中Scanner类和BufferReader类之间的区别
原文地址:https://blog.csdn.net/u014717036/article/details/52227782 java.util.Scanner类是一个简单的文本扫描类,它可以解析基本 ...
- Java中String、StringBuffer和StringBuilder之间的区别
String在Java中是字符串常量 例如 String str = "abc"; str = str + 1; System.out.println(str); 结果将是abc1 ...
- java ->String、StringBuffer、StringBuilder三者之间的区别
1.首先说运行速度,速度由快到慢排列:StringBuilder > StringBuffer > String String最慢的原因: String为字符串常量,而StringBuil ...
- Java线程池中submit()和execute之间的区别?
一: submit()方法,可以提供Future < T > 类型的返回值. executor()方法,无返回值. execute无返回值 public void execute(Runn ...
- Java中几种常用数据类型之间转换的方法
Java中几种常用的数据类型之间转换方法: 1. short-->int 转换 exp: short shortvar=0; int intvar=0; shortvar= (short) in ...
随机推荐
- %和format 细说
Python中格式化字符串目前有两种阵营:%和format,我们应该选择哪种呢? 自从Python2.6引入了format这个格式化字符串的方法之后,我认为%还是format这根本就不算个问题.不信你 ...
- Python模块学习 - Functools
Functools模块 Higher-order functions and operations on callable objects,看这个标题我都是懵逼的,这都是啥啥啥啊,赶紧拿出百度翻译:可 ...
- 448D - Codeforces
D. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes Bizon the C ...
- python基础===利用PyCharm进行Python远程调试(转)
原文链接:利用PyCharm进行Python远程调试 背景描述 有时候Python应用的代码在本地开发环境运行十分正常,但是放到线上以后却出现了莫名其妙的异常,经过再三排查以后还是找不到问题原因,于是 ...
- 浅谈linux的死锁检测 【转】
转自:http://www.blog.chinaunix.net/uid-25942458-id-3823545.html 死锁:就是多个进程(≥2)因为争夺资源而相互等待的一种现象,若无外力推动,将 ...
- Centos_Lvm_Create pv vg lv and mount
re-scan new disks without restarting CentOS re-scan new disks(/dev/sdc): #ls /sys/class/scsi_host/ h ...
- CentOS 7下安装php-redis扩展及简单使用
前言: 在本篇文章中,我将给大家介绍如何在CentOS7上安装PHP-Redis扩展以及一些简单的实用,关于如何在Centos上安装redis的,可以参考 Redis在CentOS 7上的安装部署 ...
- node起server--axios做前端请求----进行CORS--跨域请求
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
- Mysql 数据库学习笔记02 编程
一.常量 * 字符串常量 * 数值常量 * 十六进制常量 * 日期时间常量 * 位字段常量 * 布尔值 * NULL值 二.变量 * 用户变量:用户自定义变量: * 系统变量:系统内部定义的变量: 1 ...
- C++变量类型转换
1:int转换为CString CString str; str.Format("As string: %d", int); 2:double转换为CString CString ...