转载于:http://blog.youkuaiyun.com/qq_35101189/article/details/57075139
数组是一种很常见的数据结构,开始接触编程的时候多数程序都和数组相关。刚开始接触Java时也是一直使用数组写一些程序,后来越来越觉得数组这东西没法满足需求了
什么时候数组会显得力不从心,没法满足需求,需要集合类呢?
- 不知道具体数据长度
- 需要自动排序
- 存储键值对
当然,上面的情况不是绝对的,只是数组比较难满足。这时集合类(也可称为容器类)就显示了它强大的功能。
集合类的分类(图片转自http://biancheng.dnbcw.info/1000wen/359774.html)

上图中不包含Queue内容,部分Map的实现类未给出。
常见使用的有List、Set、Map及他们的实现类。
List、Set、Map接口及各实现类的特性
| 接口 | 特性 | 实现类 | 实现类特性 | 成员要求 |
| List | 线性、有序的存储容器,可通过索引访问元素 | ArrayList | 数组实现。非同步。 |
|
| Vector | 类似ArrayList,同步。 |
| ||
| LinkedList | 双向链表。非同步。 |
| ||
| Map | 保存键值对成员 | HashMap | 基于哈希表的 Map 接口的实现,满足通用需求 | 任意Object对象,如果修改了equals方法,需同时修改hashCode方法 |
| TreeMap | 默认根据自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序 | 键成员要求实现caparable接口,或者使用Comparator构造TreeMap。键成员一般为同一类型。 | ||
| LinkedHashMap | 类似于HashMap,但迭代遍历时取得“键值对”的顺序是其插入顺序或者最近最少使用的次序 | 与HashMap相同 | ||
| IdentityHashMap | 使用==取代equals()对“键值”进行比较的散列映射 | 成员通过==判断是否相等 | ||
| WeakHashMap | 弱键映射,允许释放映射所指向的对象 |
| ||
| ConcurrentHashMap | 线性安全的Map |
| ||
| Set | 成员不能重复 | HashSet | 为快速查找设计的Set | 元素必须定义hashCode() |
| TreeSet | 保持次序的Set,底层为树结构 | 元素必须实现Comparable接口 | ||
| LinkedHashSet | 内部使用链表维护元素的顺序(插入的次序) | 元素必须定义hashCode() |
在满足要求的情况下,Map应尽量使用HashMap,Set应尽量使用HashSet。
集合类的基本使用
List
List基本操作
1 ArrayList<String> arrayList = new ArrayList<String>();
2 arrayList.add("Tom");
3 arrayList.add("Jerry");
4 arrayList.add("Micky");
5 // 使用Iterator遍历元素
6 Iterator<String> it = arrayList.iterator();
7 while (it.hasNext()) {
8 String str = it.next();
9 System.out.println(str);
10 }
11 // 在指定位置插入元素
12 arrayList.add(2, "Kate");
13 // 通过索引直接访问元素
14 for (int i = 0; i < arrayList.size(); i++) {
15 System.out.println(arrayList.get(i));
16 }
17 List<String> subList = new ArrayList<String>();
18 subList.add("Mike");
19 // addAll(Collection<? extends String> c)添加所给集合中的所有元素
20 arrayList.addAll(subList);
21 // 判断是否包含某个元素
22 if (arrayList.contains("Mike")) {
23 System.out.println("Mike is include in the list");
24 }
25
26 LinkedList<String> linkedList = new LinkedList<String>();
27 linkedList.addAll(arrayList);
28 // 获取指定元素
29 System.out.println(linkedList.get(4));
30 // 获取第一个元素
31 System.out.println(linkedList.getFirst());
32 // 获取最后一个元素
33 System.out.println(linkedList.getLast());
34 // 获取并删除第一个元素
35 System.out.println(linkedList.pollFirst());
36 // 获取,但不移除第一个元素
37 System.out.println(linkedList.peekFirst());
ArrayList和LinkedList的效率比较
ArrayList添加元素的效率
1 ArrayList<String> arrList = new ArrayList<String>();
2 long startTimeMillis, endTimeMillis;
3 startTimeMillis = System.currentTimeMillis();
4 for (int i = 0; i < 10000; i++) {
5 arrList.add(0, "addString");
6 }
7 endTimeMillis = System.currentTimeMillis();
8 System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
9 + "ms");
10
11 arrList.clear();
12
13 startTimeMillis = System.currentTimeMillis();
14 for (int i = 0; i < 20000; i++) {
15 arrList.add(0, "addString");
16 }
17 endTimeMillis = System.currentTimeMillis();
18 System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
19 + "ms");
20
21 arrList.clear();
22
23 startTimeMillis = System.currentTimeMillis();
24 for (int i = 0; i < 40000; i++) {
25 arrList.add(0, "addString");
26 }
27 endTimeMillis = System.currentTimeMillis();
28 System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
29 + "ms");
30
31 arrList.clear();
32
33 startTimeMillis = System.currentTimeMillis();
34 for (int i = 0; i < 80000; i++) {
35 arrList.add(0, "addString");
36 }
37 endTimeMillis = System.currentTimeMillis();
38 System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
39 + "ms");
40
41 arrList.clear();
42
43 startTimeMillis = System.currentTimeMillis();
44 for (int i = 0; i < 160000; i++) {
45 arrList.add(0, "addString");
46 }
47 endTimeMillis = System.currentTimeMillis();
48 System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
49 + "ms");
50
51 arrList.clear();
52
53 startTimeMillis = System.currentTimeMillis();
54 for (int i = 0; i < 320000; i++) {
55 arrList.add(0, "addString");
56 }
57 endTimeMillis = System.currentTimeMillis();
58 System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
59 + "ms");
执行时间比较
| 执行次数(在0号位置插入) | ArrayList所用时间(ms) | LinkedList所用时间(ms) |
| 10000 | 31 | 0 |
| 20000 | 141 | 0 |
| 40000 | 484 | 16 |
| 80000 | 1985 | 0 |
| 160000 | 7906 | 0 |
| 320000 | 31719 | 16 |
| 执行次数(在尾部插入) | ArrayList所用时间(ms) | LinkedList所用时间(ms) |
| 10000 | 0 | 0 |
| 20000 | 15 | 0 |
| 40000 | 0 | 0 |
| 80000 | 0 | 0 |
| 160000 | 0 | 15 |
| 320000 | 0 | 16 |
| 循环输出次数(get(index)方法) | ArrayList所用时间(ms) | LinkedList所用时间(ms) |
| 10000 | 93 | 204 |
| 20000 | 188 | 797 |
| 40000 | 328 | 2734 |
| 80000 | 688 | 13328 |
| 160000 | 1594 | 62313 |
| 320000 | 2765 | 太久了…… |
因为ArrayList底层由数组实现,在0号位置插入时将移动list的所有元素,在末尾插入元素时不需要移动。LinkedList是双向链表,在任意位置插入元素所需时间均相同。所以在List中有较多插入和删除操作的情况下应使用LinkedList来提高效率,而有较多索引查询的时候使用ArrayList(使用增强型的for循环或Iterator遍历LinkedList效率将提高很多)。
Map
Map基本操作
1 HashMap<String, Integer> map = new HashMap<String, Integer>();
2 // 向Map中添加元素
3 map.put("Tom", 26);
4 map.put("Jack", 18);
5 map.put("Micky", 17);
6 map.put("Kate", 15);
7 // 根据Key获取Value
8 System.out.println("Jack is " + map.get("Jack") + " years old");
9 // 移除
10 map.remove("Micky");
11 // 遍历Map
12 for (Entry<String, Integer> entry : map.entrySet()) {
13 System.out.println("name:" + entry.getKey() + " age:"
14 + entry.getValue());
15 }
16 // Key相同的元素将被覆盖
17 map.put("Jack", 19);
18 // 根据Key获取Value
19 System.out.println("Jack is " + map.get("Jack") + " years old");
20 // 判断是否包含某个Key
21 if (map.containsKey("Tom")) {
22 System.out.println(map.get("Tom"));
23 }
24 // 判断是否包含某个Value
25 if (map.containsValue(26)) {
26 System.out.println("The map include the value 26");
27 }
28 // 判断map是否为空
29 if (!map.isEmpty()) {
30 // 获取map大小
31 System.out.println("The map's size=" + map.size());
32 }
33 // 获取Key的集合
34 for (String str : map.keySet()) {
35 System.out.println(str);
36 }
37
38 TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>();
39 treeMap.putAll(map);
40 // 输出内容按照key值排序
41 for (Entry<String, Integer> entry : treeMap.entrySet()) {
42 System.out.println("name:" + entry.getKey() + " age:"
43 + entry.getValue());
44 // name:Jack age:19
45 // name:Kate age:15
46 // name:Tom age:26
47 }
48
49 LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<String, Integer>();
50 // 向Map中添加元素
51 linkedHashMap.put("Tom", 26);
52 linkedHashMap.put("Jack", 18);
53 linkedHashMap.put("Micky", 17);
54 linkedHashMap.put("Kate", 15);
55 // 保持了插入的顺序
56 for (Entry<String, Integer> entry : linkedHashMap.entrySet()) {
57 System.out.println("name:" + entry.getKey() + " age:"
58 + entry.getValue());
59 // name:Tom age:26
60 // name:Jack age:18
61 // name:Micky age:17
62 // name:Kate age:15
63 }
Set
1 List<Integer> list = new ArrayList<Integer>(); 2 list.add(3); 3 list.add(4); 4 HashSet<Integer> hashSet = new HashSet<Integer>(); 5 hashSet.add(1); 6 hashSet.add(3); 7 hashSet.add(2); 8 hashSet.add(6); 9 // 重复元素将不能被添加 10 hashSet.add(3); 11 // 只要有元素被添加就返回true 12 if (hashSet.addAll(list)) { 13 System.out.println("Add success"); 14 } 15 // 判断是否存在某个集合 16 if (hashSet.containsAll(list)) { 17 System.out.println("The hashSet is contain 3 and 4"); 18 } 19 Iterator<Integer> it = hashSet.iterator(); 20 while (it.hasNext()) { 21 System.out.print(it.next() + " "); 22 // 1 2 3 4 6 23 // 看结果是被排序了,HashSet按照Hash函数排序,Integer值的HashCode就是其int值 24 } 25 // 换转成数组 26 Object[] integers = hashSet.toArray(); 27 for (int i = 0; i < integers.length; i++) { 28 System.out.print((Integer) integers[i]); 29 } 30 //移除元素 31 hashSet.remove(3); 32 33 TreeSet<String> treeSet = new TreeSet<String>(); 34 treeSet.add("C"); 35 treeSet.add("A"); 36 treeSet.add("D"); 37 treeSet.add("B"); 38 for (Iterator<String> strIt = treeSet.iterator(); strIt.hasNext();) { 39 System.out.print(strIt.next()); 40 // ABCD 按照字母顺序 41 } 42 LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>(); 43 linkedHashSet.add("C"); 44 linkedHashSet.add("A"); 45 linkedHashSet.add("D"); 46 linkedHashSet.add("B"); 47 for (Iterator<String> linkedIt = linkedHashSet.iterator(); linkedIt 48 .hasNext();) { 49 System.out.print(linkedIt.next()); 50 // CADB 按照插入顺序 51 }
本文详细介绍了Java中的集合类,包括List、Set、Map及其不同实现类的特点和应用场景,并提供了具体的代码示例。


被折叠的 条评论
为什么被折叠?



