前言:java
数组Array和集合的区别:数组
一、数组是大小固定的,而且同一个数组只能存放类型同样的数据(基本类型/引用类型)安全
二、JAVA集合能够存储和操做数目不固定的一组数据。数据结构
三、若程序时不知道究竟须要多少对象,须要在空间不足时自动扩增容量,则须要使用容器类库,array不适用。 多线程
注:使用相应的toArray()和Arrays.asList()方法能够相互转换。性能
集合:优化
集合类存放于Java.util包中。spa
集合类存放的都是对象的引用,而非对象自己,出于表达上的便利,咱们称集合中的对象就是指集合中对象的引用。.net
集合类型主要有三种:set(集)、list(列表)、map(映射)。命令行
1、Collection接口
Collection是最基本的集合接口,一个Collection表明一组Object,即Collection的元素。Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
如何遍历Collection中的每个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子便可逐一访问Collection中每个元素。典型的用法以下:
Iterator it = collection.iterator(); // 得到一个迭代子 while(it.hasNext()) { Object obj = it.next(); // 获得下一个元素 }
由Collection接口派生的两个接口是List和Set。
2、Set
Set接口一样是Collection接口的一个子接口,Set不包含重复的元素。
HashSet:使用hashmap的一个集的实现。虽然集定义成无序,但必须存在某种方法能高效地找到一个对象。使用一个hashmap对象实现集的存储和检索操做时在固定时间内实现的。
TreeSet:在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象得到第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap。
为优化hashset空间的使用,能够调优初始容量和负载因子。TreeSet
不包含调优选项,由于树老是平衡的,保证了插入、删除、查询的性能的高效。
当您要从集合中以有序的方式抽取元素时,TreeSet
实现会有用处。为了能顺利进行,添加到TreeSet
的元素必须是可排序的。
import java.util.*; public class SetExample { public static void main(String args[]) { Set set = new HashSet(); set.add("Bernadine"); set.add("Elizabeth"); set.add("Gene"); set.add("Elizabeth"); set.add("Clara"); System.out.println(set); Set sortedSet = new TreeSet(set); System.out.println(sortedSet); } }
[Gene, Clara, Bernadine, Elizabeth] [Bernadine, Clara, Elizabeth, Gene]
3、List
List接口继承了Collection接口,定义一个容许重复项的有序集合。该接口不但可以对列表的一部分进行处理,还添加了面向位置的操做。
实际上有两种list:一种是基本的ArrayList,其优势在于随机访问元素,另外一种是更强大的LinkedList,它并非快速随机访问设计的,而是具备更通用的方法。
List : 次序是List最重要的特色:它保证维护元素特定的顺序。
ArrayList : 由数组实现的List。容许对元素进行快速随机访问,可是向List中间插入与移除元素的速度很慢。
LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则相对较慢。还具备下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList能够看成堆栈、队列和双向队列使用。
Vector:实现一个相似数组同样的表,自动增长容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中同样。你也能够用一个迭代器从一个Vector中检索对象Vector是惟一的同步容器类!!
stack:这个类从vector派生而来,并增长了方法实现栈,一种后进先出的存储结构。
List的用法示例:
package collection; import java.util.*; public class SetExample { public static void main(String[] args) { List linkedList = new LinkedList(); for (int i = 0; i <= 5; i++) { linkedList.add("a"+i); } System.out.println(linkedList); linkedList.add(3,"a100"); System.out.println(linkedList); linkedList.set(6,"a200"); System.out.println(linkedList); System.out.println(linkedList.get(2)); System.out.println(linkedList.indexOf("a3")); linkedList.remove(1); System.out.println(linkedList); } }
4、list和set对比
Set子接口:无序,不容许重复,检索元素效率低下,删除和插入效率高,插入和删除不会引发元素位置改变。
List子接口:有序,能够有重复元素,和数组相似,List能够动态增加,查找元素效率高,插入删除元素效率低,由于会引发其余元素位置改变。
Set和List具体子类:
Set
|————HashSet:以哈希表的形式存放元素,插入删除速度很快。
List
|————ArrayList:动态数组
|————LinkedList:链表、队列、堆栈。
5、map
map接口不是Collection接口的继承。
不重复的键到值的映射。
Map.Entry 接口
map的entrySet()方法返回一个实现map.entry接口的对象集合。集合中每一个对象都是底层map中一个特定的键值对。
HashMap 类和 TreeMap 类
在map中插入、删除和定位元素,HashMap是最好的选择。但若是您要按顺序遍历键,那么TreeMap 会更好。根据集合大小,先把元素添加HashMap,再把这种映射转换成一个用于有序键遍历的TreeMap 可能更快。
为了优化hashmap空间的使用,您能够调优初始容量和负载因子。这个treeMap没有调优选项,由于该树总处于平衡状态。
hashtable:实现一个映象,全部的键必须非空。为了能高效的工做,定义键的类必须实现hashcode()方法和equal()方法。这个类时前面Java实现的一个继承,而且一般能在实现映象的其它类中更好地使用。
hashmap:实现一个映象,运行存储空对象,并且容许键是空(因为键必须是惟一的,固然只能有一个空)。
WeakHashMap:若是有一个键对于一个对象而言再也不被引用,键将被舍弃,WeakHashMap在具备大量数据时使用。
TreeMap: 实现这样一个映象,对象是按键升序排列的。
map的使用示例:
如下程序演示了具体map类的使用。该程序对自命令行传递的词进行频率计数。hashmap起初用于数据存储。后来,映射被转换为TreeMap以显示有序的键列列表。
package collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; public class MapExample { public static void main(String[] args) { String[] array = {"a","b","c","d","e"}; Map map = new HashMap(); Integer ONE = new Integer(1); for (int i=0, n=array.length; i<n; i++) { String key = array[i]; int frequency = i+1; map.put(key, frequency); } System.out.println(map); Map sortedMap = new TreeMap(map); System.out.println(sortedMap); //hashmap的同步 Map map1 = Collections.synchronizedMap(map); System.out.println(map1); } }
结果:
6、解惑:
一、什么是iterator
对集合的遍历,遍历的时候不建议修改集合。
二、Iterator与ListIterator有什么区别?
Iterator:只能正向遍历集合
ListIerator:继承Iterator,能够双向列表遍历
三、HashMap与HashTable有什么区别?
HashMap容许空值做为键或值,不一样步的,迭代时采用的是快速失败机制
HashTable不容许空值,同步的
注:有多线程的可能时,使用hashtable,反之使用hashmap。非线程安全的数据结构能带来更好地性能。
若是未来有可能须要按顺序获取键值对,hashmap是更好地选择,由于hashmap的一个子类LinkedHashMap。
若是多线程时使用hashmap,Collections.synchronizedMap()能够代替,总的来讲HashMap更灵活。
四、在Hashtable上下文中同步是什么意思?
同步意味着在一个时间点只能有一个线程能够改变哈希表,任何线程在执行hashtable的更新操做前须要获取对象锁,其它线程等待锁的释放。
五、为何Vector不推荐使用?
使用时ArrayList优先于Vector,Vector是同步的,性能会低一些,若是迭代一个vector,还要加锁,以免其余线程同一时刻改变集合,加锁效率更慢。