目录
集合家族的注意事项
【一】介绍
【二】collection
【三】map
【四】接口实现
4.1 Collection
4.1.1 List接口
4.1.2 ArrayList
4.1.3 LinkedList
4.1.4 Vector
4.1.6 Stack
4.2 Set
4.3 Map
4.4 Queue
【五】异同点
5.1、Vector和ArrayList
5.2、Aarraylist和Linkedlist
5.3、HashMap与TreeMap
5.4、hashtable与hashmap
【六】对集合的选择
6.1、对List的选择
6.2、对Set的选择
6.3、对Map的选择
【七】链接
什么是集合(Collection)?集合就是“由若干个确定的元素所构成的整体”
在Java中,如果一个Java对象可以在内部持有若干其他Java对象,并对外提供访问接口,我们把这种Java对象称为集合。很显然,Java的数组可以看作是一种集合
Collection接口是最基本的集合接口,它不提供直接的实现。
Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
Collection所代表的是一种规则,它所包含的元素都必须遵循一条或者多条规则。如有些允许重复而有些则不能重复、有些必须要按照顺序插入而有些则是散列,有些支持排序但是有些则不支持。
在Java中所有实现了Collection接口的类都必须提供两套标准的构造函数,一个是无参,用于创建一个空的Collection,一个是带有Collection参数的有参构造函数,用于创建一个新的Collection,这个新的Collection与传入进来的Collection具备相同的元素。
List:一种有序列表的集合,元素可重复Set:一种保证没有重复元素的集合,无序的结构 import java.util.*; public class Test{ public static void main(String[] args) { List<String> list=new ArrayList<String>(); list.add("Hello"); list.add("World"); list.add("HAHAHAHA"); //第一种遍历方法使用 For-Each 遍历 List for (String str : list) { //也可以改写 for(int i=0;i<list.size();i++) 这种形式 System.out.println(str); } //第二种遍历,把链表变为数组相关的内容进行遍历 String[] strArray=new String[list.size()]; list.toArray(strArray); for(int i=0;i<strArray.length;i++) //这里也可以改写为 for(String str:strArray) 这种形式 { System.out.println(strArray[i]); } //第三种遍历 使用迭代器进行相关遍历 Iterator<String> ite=list.iterator(); while(ite.hasNext())//判断下一个元素之后有值 { System.out.println(ite.next()); } } }Map这种键值(key-value)映射表的数据结构,作用就是能高效通过key快速查找value(元素)
import java.util.*; public class Test{ public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value3"); //第一种:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //第二种 System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第三种:推荐,尤其是容量大时 System.out.println("通过Map.entrySet遍历key和value"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //第四种 System.out.println("通过Map.values()遍历所有的value,但不能遍历key"); for (String v : map.values()) { System.out.println("value= " + v); } } }List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。
ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。
size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。
ArrayList擅长于随机访问。同时ArrayList是非同步的。
同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。所以它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。
由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。
与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List: List list = Collections.synchronizedList(new LinkedList(…));
与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。实现了Set接口的集合有:EnumSet、HashSet、TreeSet。
4.2.1 EnumSet是枚举的专用Set。所有的元素都是枚举类型。
4.2.2 HashSetHashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。
4.2.3 TreeSet基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。实现map的有:HashMap、TreeMap、HashTable、Properties、EnumMap。
4.3.1 HashMap以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。
4.3.2 TreeMap键以某种排序规则排序,内部以red-black(红-黑)树数据结构实现,实现了SortedMap接口
4.3.3 HashTable也是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式,不过性能比HashMap要低
队列,它主要分为两大类,一类是阻塞式队列,队列满了以后再插入元素则会抛出异常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。另一种队列则是双端队列,支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。
出处:http://blog.csdn.net/softwave/article/details/4166598
ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!
