2015我想和Java聊聊之集合大阅兵
来源:互联网 发布:买了域名要主机吗 编辑:程序博客网 时间:2024/04/28 10:45
java的容器和数组是java里很常用的一块。上一章写HashMap和Hashtable的区别,其实Hashtable是老旧的类别,除了特殊的对 线程安全有要求的场景,一般来说,是弃之不用的,同样情况的还有Vetor和stack等。一般来说,JAVA的可变数组下常用的为ArrayList、 LinkedList、HashSet、TreeSet、LinkedHashSet,映射表下常用的为HashMap、LinkedHashMap,TreeMap。现连同数组一起来介绍他们的区别和常用场景。
数组
《Thinking in java》第16章对数组有如下:数组是效率最高的存数和随机访问对方引用序列的方式,数组是限行序列,这使得数组元素访问非常迅速。不过数组在它的生命周期里长度是固定的,应用场景不如ArrayList丰富。数组对泛型的支持也不太好。比如:
Object[] os = new Object[]{3,"a","asdasd",5,6f}; Arrays.sort(os); System.out.println(Arrays.toString(os));
会抛出异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
数组速度很快,可以本身除了object的方法外仅有length方法,实际使用中要与Arrays结合:
Arrays.sort 排序;
Arrays.toString 输出为字符串
Arrays.fill 全部填充为某个对象
Arrays.binarySearch 查找对象(适用于Arrays.sort 排序后)
List(列表)
ArrayList的长度是可变的。ArrayList底层是由数组支持,而LinkedList是由双向链表实现,每个对象包含数据和链表的前一个和后一个元素的引用,如果经常在list里删除或者插入元素,用linkedlist更合适,否则用arraylist更快;ArrayList在插入数据的时候,必须创建空间将它所有的引用向前移动,这样随着arraylist的增加而越来越慢,Linkedlist只需要链接新的元素,而不需要修改列表剩余的元素。
由于ArrayList底层是由数组支持,所以数组和List之间是可以通过Arrays.asList互相转换的
String[] ss = new String[]{"1","asda","asdasdasda","zxzzxczcx"}; List<String> list = Arrays.asList(ss);
不过需要注意,由于数组长度是固定的,所以转换后的List长度也是固定的,一旦调用修改集合尺寸的方法,就会抛出UnsupportedOperationException异常,所以需要将
Arrays.asList的结果作为构造器的参数传给List:
List list2 = new ArrayList<String>(list);
和数组的Arrays类似的是,List具有一个Collections工具类,
Collections.replaceAll 替换所有符合条件的对象;
Collections.fill 全部替换;
Collections.sort 排序;
Collections.binarySearch 查询;
Set(集)
Set和List最直观的区别是Set是不可重复的(Set存放的是对象的引用,没有重复对象;List的特征是其元素以线性方式存储,集合中可以存放重复对象),所以在HashMap维护Key值需要用到HashSet
HashSet最快最常用,LinkedHashSet保持元素的插入顺序,TreeSet基于TreeMap,生成一个总是处于排序状态的set
由于List和Set 都extends了Collection,所以Collections的一部分方法也适用于Set,比如:
Collections.max(set);
Collections.min(set);
Map(映射表/关联数组)
HashMap是无序的,利用HashCode散列的数据结构,增快查询速度;LinkedHashMap键值对是顺序插入的,在迭代输出的时候更快,new LinkedHashMap<String, Object>(6,0.75f,true),采用基于访问的最近最少使用的算法(LRU),没有被访问的元素会被排在最前面,在维护散列元素的同时还要维护链表。
Map的性能瓶颈在于随机读取数据时候,对键的查询,由于键是使用简单的现行查询,速度很慢,而HashMap利用上散列(HashCode)使得查询速度加快。HashMap不继承Collection,所以不具备Iterator方法,但是它内部维护了Keyset和EntrySet,利用entrySet可以进行遍历:
Iterator<Entry<String,Object>> its = map.entrySet().iterator();
LinkedHashMap和LinkedHashSet以及LinkedList都维护了双向队列的方法,因此速度会相应减慢。
免锁集合
Vetor和Hashtable都是线程安全的集合,但是在单线程情况下性能较差而被淘汰,可以上述的集合并不能满足线程安全场景的需求,往往在多线程情况下需要对这些集合的操作加锁,这不免增加了代码的冗余和性能的下降,为了性能调优,JDK1.5引入了java.util.concurrent包,包里有很多免锁集合:CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentHashMap。以ConcurrentHashMap为例:
ConcurrentHashMap锁的方式是稍微细粒度的。 ConcurrentHashMap将hash表分为16个桶(默认值),诸如get,put,remove等常用操作只锁当前需要用到的桶。
试想,原来 只能一个线程进入,现在却能同时16个写线程进入(写线程才需要锁定,而读线程几乎不受限制,之后会提到),并发性的提升是显而易见的。 更令人惊讶的是ConcurrentHashMap的读取并发,因为在读取的大多数时候都没有用到锁定,所以读取操作几乎是完全的并发操作,而写操作锁定的粒度又非常细,比起之前又更加快速(这一点在桶更多时表现得更明显些)。只有在求size等操作时才需要锁定整个表。
根据测试,ConcurrentHashMap的性能比同步的HashMap快一倍左右。免锁集合在后续的并发和线程安全这块会详细介绍。
- 2015我想和Java聊聊之集合大阅兵
- 2015我想和Java聊聊之NIO读写文件
- 2015我想和Java聊聊之HashTable和HashMap的区别
- 2015我想和Java聊聊之StringBuffer是如何保证线程安全的
- 我想和你聊聊Machine Learning
- 大阅兵盛况地面装备高清图片集合
- 大阅兵盛况地面装备高清图片集合
- 国庆大阅兵
- 许可证大阅兵
- Java之三大集合
- 大阅兵大实力 TCL H8800助力阅兵前线指挥车
- 音乐制作软件大阅兵
- UI设计模式大阅兵
- UI设计模式大阅兵
- UI设计模式大阅兵
- java提高篇之集合大家族
- java集合大家族之Map
- java集合大家族之总结
- 更高级多态性类型 和 特设多态性
- Hive 在多维统计分析中的应用 & 技巧总结
- appium 真机测试问题 出现 instruments crashed on startup
- CRF++总结 (1)(2)【转】
- ImageView使用网络图片资源
- 2015我想和Java聊聊之集合大阅兵
- LeetCode 32 Longest Valid Parentheses (C,C++,Java,Python)
- linuex 命令 forever
- 光驱上是黄色感叹号
- ETL工具Pentaho Kettle的transformation和job集成
- Linux 挂载概念 理解
- 资源文件
- eclipse启动tomcat无法访问
- C语言函数名与函数指针详解