1 /*****************
2 ***第七章 集合
3 *******知识点:
4 **************1.Collection和Iterator接口
5 ******************1.1 Collection接口简介
6 ******************1.2 Iterator接口简介
7 ******************1.3 Map接口简介
8 **************2.Set接口
9 ******************2.1 HashSet类
10 ******************2.2 TreeSet类
11 ******************2.3 EnumSet类
12 **************3.List接口
13 ******************3.1 ArrayList类
14 ******************3.2 LinkedList类
15 ******************3.3 Vector类
16 ******************3.4 Stack类
17 **************4.Queue接口
18 ******************4.1 PriorityQueue类
19 **************5.Map接口
20 ******************5.1 HashMap类
21 ******************5.2 Hashtable类
22 ******************5.3 SortedMap接口
23 ******************5.4 TreeMap类
24 ******************5.5 WeakHashMap类
25 ******************5.6 IdentityHashMap类
26 ******************5.7 EnumMap类
27 **************6.集合操作工具类
28 ******************6.1 排序操作
29 ******************6.2 查找,替换操作
30 ******************6.3 同步控制
31 ******************6.4 总结
32 */
33 import java.util.*;
34
35 /*
36 * 演示需用类
37 */
38 class Person implements Comparable{
39 private int id;
40 private String name;
41 Person(){
42 this.id = 0;
43 this.name = "无名氏";
44 }
45
46 Person(int id, String name){
47 this.id = id;
48 this.name = name;
49 }
50
51 public String toString(){
52 return "id:" + id + ",name:" +name;
53 }
54
55 //重写接口中的方法 用于比较
56 public int compareTo(Object o){
57 Person p = (Person) o;
58 int result = id < p.id ? 1 : (id == p.id ? 0 : -1); //降序
59 //int result = id > p.id ? 1 : (id == p.id ? 0 : -1); //降序
60 if(result == 0){
61 result = name.compareTo(p.name);//注意区别:这里调用String的compareTo方法
62 }
63 return result;
64 }
65 }
66
67 /*
68 * 演示枚举类
69 */
70 enum MyEnum{
71 BLACK,WIHTE,RED,BLUE,GREEN
72 }
73
74 public class test7{
75 public static void main(String[] args){
76 showDemo("1.Collection和Iterator接口");
77 demoCollectionAndIterator(); //1.Collection和Iterator接口
78
79 showDemo("2.Set接口");
80 demoSet(); //2.Set接口
81
82 showDemo("3.List接口");
83 demoList(); //3.List接口
84
85 showDemo("4.Queue接口");
86 demoQueue(); //4.Queue接口
87
88 showDemo("5.Map接口");
89 demoMap(); //5.Map接口
90
91 showDemo("6.集合操作工具类");
92 demoTools(); //6.集合操作工具类
93 }
94
95 /**1.Collection和Iterator接口**/
96 public static void demoCollectionAndIterator(){
97 /**1.1 Collection接口简介**/
98 //Collection接口是集合父接口之一 实现子接口有 Set接口、List接口
99 //其中Set接口:不能包含重复的元素
100 //List接口:一个有序的集合
101
102 /**1.2 Iterator接口简介**/
103 //Iterator接口是迭代器
104 //用于遍历集合中的元素
105
106 /**1.3 Map接口简介**/
107 //Map接口是集合父接口之一 实现子类有SortMap、HashMap
108 //包含了key-value 俗称键值对 其中 key不能重复
109 }
110
111 /**2.Set接口**/
112 public static void demoSet(){
113 //Set接口:不能包含重复的元素、允许包含值为null的元素但只能有一个
114
115 /**2.1 HashSet类**/
116 //HashSet类按照哈希算法来存取集合中的对象,存取速度比较快
117 System.out.println("演示HashSet类=======");
118 HashSet h_HashSet = new HashSet();
119 Person p1 = new Person();
120 h_HashSet.add("1");//字符串
121 h_HashSet.add('2');//字符
122 h_HashSet.add(3);//整型
123 h_HashSet.add(true);//布尔型
124 h_HashSet.add(1.0);
125 h_HashSet.add(new Integer(3));//不会被添加 因为重复了
126 h_HashSet.add(p1);//对象
127 System.out.println("集合长度为:" + h_HashSet.size());//获取集合长度
128
129 Iterator i_Iterator = h_HashSet.iterator();//得到遍历的迭代器
130 while(i_Iterator.hasNext()){
131 Object o = (Object)(i_Iterator.next());//通过迭代器返回元素 注意返回为Object类型
132 System.out.println("集合元素:" + o);//需注意如果是自定义的类型 需要重写toString方法
133 }
134
135 System.out.println("判断集合是否为空:" + h_HashSet.isEmpty());//判断集合是否为空
136 h_HashSet.remove(3);//删除元素
137 h_HashSet.remove((float)1.0);//不能删除元素 类型不匹配
138
139 System.out.println("集合长度为:" + h_HashSet.size());//获取集合长度
140 i_Iterator = h_HashSet.iterator();
141 while(i_Iterator.hasNext()){
142 Object o = (Object)(i_Iterator.next());//通过迭代器返回元素 注意返回为Object类型
143 System.out.println("集合元素:" + o);
144 }
145
146 System.out.println(h_HashSet);//将集合打印出来
147
148 /**2.2 TreeSet类**/
149 //TreeSet类是一个有序集合,元素将按照升序排列,缺省是按照自然排序进行排列。
150 //所以该集合中的元素要实现Comparable接口或者有一个自定义的比较器
151 //另外集合中的元素存储顺序跟加入的顺序无关
152 System.out.println("演示TreeSet类=======");
153 TreeSet t_TreeSet1 = new TreeSet();
154 t_TreeSet1.add("aaaa");
155 t_TreeSet1.add("ccc");
156 t_TreeSet1.add("ac");
157 t_TreeSet1.add("bc");
158 Iterator i_Iterator_TreeSet = t_TreeSet1.iterator();
159 while(i_Iterator_TreeSet.hasNext()){
160 Object o = i_Iterator_TreeSet.next();
161 System.out.println("集合对象:" + o);//注意输出结果跟加入顺利对比 发现无关
162 }
163
164 System.out.println("集合中第一个对象:" + (Object)t_TreeSet1.first());//返回第一个元素
165 System.out.println("集合中第一个对象:" + (Object)t_TreeSet1.last());//返回最后一个元素
166
167 System.out.println("返回不小于acd的集合对象:" + (Object)t_TreeSet1.ceiling("acd"));
168 //返回一个不小于acd的集合元素(非随机 就是一个且最接近的一个)
169
170 Person p1_TreeSet = new Person();
171 Person p2_TreeSet = new Person(0,"aaa");
172 Person p3_TreeSet = new Person(1,"aaa");
173
174 TreeSet t_TreeSet2 = new TreeSet();
175 t_TreeSet2.add(p1_TreeSet);
176 t_TreeSet2.add(p2_TreeSet);
177 t_TreeSet2.add(p3_TreeSet);
178
179 System.out.println("集合中所有对象:" + t_TreeSet2);
180
181
182 /**2.3 EnumSet类**/
183 //这个类是1.5开始有的
184 //目前个人使用量几乎为零,很少使用
185 //其使用方式和普通的Set没有区别,只是构造方法有一些特殊的而已
186 //多种添加集合元素方式
187 System.out.println("演示EnumSet类=======");
188
189 //第一种创建一个指定类型的空集合 然后再添加元素
190 EnumSet<MyEnum> e_EnumSet1 = EnumSet.noneOf(MyEnum.class);
191 e_EnumSet1.add(MyEnum.BLACK);
192 e_EnumSet1.add(MyEnum.RED);
193 e_EnumSet1.add(MyEnum.BLUE);
194 System.out.println("e_EnumSet集合中的对象:" + e_EnumSet1);
195
196 //第二种创建一个指定类型的所有数据集合
197 EnumSet<MyEnum> e_EnumSet2 = EnumSet.allOf(MyEnum.class);
198 System.out.println("e_EnumSet集合中的对象:" + e_EnumSet2);
199
200 //第三种创建一个指定类型的指定初始化数据的集合
201 EnumSet<MyEnum> e_EnumSet3 = EnumSet.of(MyEnum.WIHTE,MyEnum.GREEN);
202 System.out.println("e_EnumSet集合中的对象:" + e_EnumSet3);
203
204 //第四种创建一个指定类型的指定数据范围的集合
205 EnumSet<MyEnum> e_EnumSet4 = EnumSet.range(MyEnum.WIHTE,MyEnum.BLUE);//从WIHTE到BLUE 的所有元素
206 System.out.println("e_EnumSet集合中的对象:" + e_EnumSet4);
207
208
209 //总结:
210 // 1.HashSet 速度快 且使用居多
211 // 2.TreeSet 自动实现排序(需要为元素实现比较器)
212 // 3.EnumSet 枚举 然并卵
213 // 最后对时间效率有要求使用 HashSet 对排序有要求使用 TreeSet EnumSet(忘了它吧)
214 }
215
216 /**3.List接口**/
217 public static void demoList(){
218 //List接口:一个有序的集合 对插入的顺序有序
219
220 /**3.1 ArrayList类**/
221 //1.基于数组实现的List类
222 //2.查找和定位操作快
223 //3.添加和删除操作慢
224 //4.线程不安全
225 System.out.println("演示ArrayList类=======");
226 ArrayList a_ArrayList = new ArrayList();//默认10个长度 后面可以动态加载
227 for(int i = 0; i < 10; i++){
228 a_ArrayList.add(i); //加载元素
229 }
230
231 //使用foreach遍历集合
232 for(Object j :a_ArrayList){
233 System.out.println("元素:" + j);
234 }
235
236 //使用get方法遍历
237 for(int i= 0 ;i < 10 ; i++){
238 System.out.println("元素:" + a_ArrayList.get(i));
239 }
240 //推荐使用后者遍历
241 System.out.println(a_ArrayList);//将所有元素打印出来
242 //更多方法使用详见API
243
244
245 /**3.2 LinkedList类**/
246 //1.基于链表实现的List类
247 //2.查找和定位操作慢
248 //3.添加和删除操作快
249 //4.线程不安全
250 //使用跟ArrayList相似 具体使用时查看API即可 需注意实现的方式采用的是链表
251 System.out.println("演示LinkedList类=======");
252
253 /**3.3 Vector类**/
254 //1.基于数组实现的List类
255 //2.线程安全
256 //3.已经被ArrayList类取代得差不多了
257 //使用跟ArrayList相似 具体使用时查看API即可 一般不会使用 毕竟ArrayList几乎可以取代它了无论是从执行效率还是功能上
258 System.out.println("演示Vector类=======");
259
260 /**3.3 Stack类**/
261 //1.Vector类的子类
262 //2.实现模拟栈操作
263 System.out.println("演示Stack类=======");
264 Stack s_Stack = new Stack();
265 System.out.println("是否为空栈:" + s_Stack.isEmpty());
266 for(int i = 0 ;i < 10; i++){
267 s_Stack.push("元素" + i);//入栈
268 }
269 System.out.println("栈元素有:" + s_Stack);
270 String str_Stack = "元素3";
271 System.out.println("元素3在第:" + (s_Stack.search((Object) str_Stack)) + "位上");//返回在堆栈中的位置 以1开始
272
273 System.out.println("栈顶元素是:" + s_Stack.peek());
274
275 //删除前先判断是否为空栈
276 if(!s_Stack.isEmpty()){
277 System.out.println("移除栈顶元素是:" + s_Stack.pop());
278 }
279 System.out.println("栈元素有:" + s_Stack);
280
281 //总结:
282 //1.如果需要遍历List集合元素,对应ArrayList、Vector集合,则应该使用随机访问方法(get)来遍历集合元素,
283 // 这样性能更好。对应LinkedList集合,则应采用迭代器(Iterator)来遍历集合元素。
284 //2.如果需要经常执行插入、删除操作来改变集合大小,则应该使用LinkedList集合,而不是ArrayList
285 //3.如果需要查询和定位操作比较频繁时,则应该使用ArrayList集合,而不是LinkedList
286 //4.如果多条线程需要同时访问List集合中的元素,可以考虑使用Vector这个同步实现。
287 // 或者使用ArrayList然后再手动设置加锁(推荐后者)
288 }
289
290 /**4.Queue接口**/
291 public static void demoQueue(){
292 //Queue接口:优先队列集合
293 //本质上就是一个最小堆
294 //很少用到 了解即可
295
296 /**4.1 PriorityQueue类**/
297 }
298
299 /**5.Map接口**/
300 public static void demoMap(){
301 //Map接口:实现键值对的接口
302
303 /**5.1 HashMap类**/
304 System.out.println("演示HashMap类=======");
305 //不同步,故线程不安全
306 //一键值 (键不同时,值可以相同 但键不能相同 可以为null)
307 // 初始化随机种子
308 Random r = new Random();
309 // 新建HashMap
310 HashMap map_HashMap = new HashMap();
311 // 添加操作
312 map_HashMap.put("one", r.nextInt(10));
313 map_HashMap.put("two", r.nextInt(10));
314 map_HashMap.put("two", r.nextInt(10));//不会被添加因为存在该键了
315 map_HashMap.put(null, null);//可以为空
316 map_HashMap.put("two1", r.nextInt(10));
317 map_HashMap.put("three", r.nextInt(10));
318 // 打印出map
319 System.out.println("map_HashMap:"+map_HashMap );
320
321 // 通过entrySet-Iterator遍历key-value
322 System.out.println("通过entrySet-Iterator遍历key-value");
323 Iterator iter_HashMap1 = map_HashMap.entrySet().iterator();
324 while(iter_HashMap1.hasNext()) {
325 Map.Entry entry = (Map.Entry)iter_HashMap1.next();
326 System.out.println("next : "+ entry.getKey() +" - "+entry.getValue());
327 }
328
329 //通过keyset - Iterator遍历key-value
330 System.out.println("通过keyset - Iterator遍历key-value");
331 Iterator iter_HashMap2 = map_HashMap.keySet().iterator();
332 while (iter_HashMap2.hasNext()){
333 Object key = iter_HashMap2.next();
334 Object val = map_HashMap.get(key);
335 System.out.println("next : "+ key +" - "+ val);
336 }
337 // HashMap的键值对个数
338 System.out.println("size:"+map_HashMap.size());
339 // containsKey(Object key) :是否包含键key
340 System.out.println("contains key two : "+map_HashMap.containsKey("two"));
341 System.out.println("contains key five : "+map_HashMap.containsKey("five"));
342 // containsValue(Object value) :是否包含值value
343 System.out.println("contains value 0 : "+map_HashMap.containsValue(new Integer(0)));
344 // remove(Object key) : 删除键key对应的键值对
345 map_HashMap.remove("three");
346 System.out.println("map:"+map_HashMap );
347 // clear() : 清空HashMap
348 map_HashMap.clear();
349 // isEmpty() : HashMap是否为空
350 System.out.println((map_HashMap.isEmpty()?"map_HashMap is empty":"map_HashMap is not empty") );
351
352
353 //两种遍历方式 推荐entrySet-Iterator这种方法 效率要高点
354 //对于keySet其实是遍历了2次,一次是转为iterator,一次就从hashmap中取出key所对于的value。
355 //而entryset只是遍历了1次,他把key和value都放到了entry中,所以就快了。
356
357 /**5.2 Hashtable类**/
358 //用法跟HashMap 差不多
359 //区别:
360 //1.Hashtable 是同步的 即线程安全 在多线程下可以直接使用 而HashMap则要手动设置同步
361 //2.Hashtable 不管key 或者value 均不允许出现null
362 //3.继承不同 Hashtable ——Dictionary 而HashMap——AbstractMap
363 //4.初始化大小和扩容方式不同
364 //5.历史遗留问题导致Hashtable 还使用Enumeration方式遍历元素
365 //最后推荐使用HashMap
366
367 /**5.3 SortedMap接口**/
368 // 保证按照键的升序排列的映射,可以按照键的自然顺序(参见 Comparable 接口)进行排序,
369 //或者通过创建有序映射时提供的比较器进行排序
370 //所以所有的键必须是可以比较的
371
372 /**5.4 TreeMap类**/
373 //TreeMap是SortedMap接口的基于红黑树的实现
374 //此类保证了映射按照升序顺序排列关键字, 根据使用的构造方法不同,可能会按照键的类的自然顺序进行排序
375 //注意1:此实现不是同步的。不是线程安全的。
376 //注意2:TreeMap是用键来进行升序顺序来排序的。通过Comparable 或 Comparator来排序。
377 //注意3:由所有此类的“collection 视图方法”所返回的迭代器都是快速失败的。
378 //注意4:和HashMap一样,如果插入重复的元素,后面的元素会覆盖前面的。
379 //注意5: 键不可以为null,但是值可以为null
380 System.out.println("演示TreeMap类=======");
381 Random r_TreeMap = new Random();
382 TreeMap t_TreeMap = new TreeMap();
383 Person p_TreeMap1 = new Person();
384 Person p_TreeMap2 = new Person(1,"aaaa");
385 Person p_TreeMap3 = new Person(2,"aaaa");
386 Person p_TreeMap4 = new Person(0,"aaaa");
387 t_TreeMap.put(r_TreeMap.nextInt(10),p_TreeMap1);
388 t_TreeMap.put(r_TreeMap.nextInt(10),p_TreeMap2);
389 t_TreeMap.put(r_TreeMap.nextInt(10),p_TreeMap3);
390 t_TreeMap.put(r_TreeMap.nextInt(10),p_TreeMap4);
391 t_TreeMap.put(r_TreeMap.nextInt(10),null); //键不可以为null 值可以
392 System.out.println("集合中元素有:" + t_TreeMap);
393
394 for(Object o:t_TreeMap.values()){
395 System.out.println("元素值:" + o);
396 }
397 //判断是否存在键
398 System.out.println("是否包含键值为3的键:" + t_TreeMap.containsKey(new Integer(3)));
399
400 //判断是否存在值
401 System.out.println("是否包含p_TreeMap1对象:" + t_TreeMap.containsValue((Object)p_TreeMap1));//是否存在p_TreeMap1
402 System.out.println("是否包含:" + t_TreeMap.containsValue(new Person()));//重新new对象跟原有对象不一样
403
404 //判断是否存在值
405 System.out.println("是否包含new Person(4,1111)对象:" + t_TreeMap.containsValue(new Person(4,"1111")));
406
407
408 /**5.5 WeakHashMap类**/
409 //WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,
410 //如果一个key不再被外部所引用,那么该key可以被GC回收。
411 //一般很少用到
412 //用法想见API 跟HashMap用法差不多
413
414 /**5.6 IdentityHashMap类**/
415 // IdentityHashMap类是一种允许key 的内容可以重复的集合类
416 //一般很少用到
417 //用法想见API 跟HashMap用法差不多
418
419 /**5.7 EnumMap类**/
420 //1. 使用EnumMap时,必须指定枚举类型。
421 //2. key不能为null
422 //3. EnumMap内部以数组实现,性能更好。
423 System.out.println("演示EnumMap类=======");
424 EnumMap e_EnumMap = new EnumMap(MyEnum.class);
425 e_EnumMap.put(MyEnum.BLACK,"黑色");
426 e_EnumMap.put(MyEnum.WIHTE,"白色");
427 e_EnumMap.put(MyEnum.RED,"红色");
428 System.out.println("集合对象有:" + e_EnumMap);
429 Iterator i_EnumMap = e_EnumMap.entrySet().iterator();
430 while(i_EnumMap.hasNext()){
431 Map.Entry entry_EnumMap = (Map.Entry)i_EnumMap.next();
432 System.out.println("对象——key:" + entry_EnumMap.getKey()+ ",value:"+entry_EnumMap.getValue());
433 }
434
435 }
436
437 /**6.集合操作工具类**/
438 public static void demoTools(){
439 //Collections类是一个集合操作工具类
440 /**6.1 排序操作**/
441 Person p_Collections1 = new Person(1,"黄");
442 Person p_Collections3 = new Person(3,"李");
443 Person p_Collections2 = new Person(2,"赵");
444 Person p_Collections4 = new Person(4,"钱");
445 List l_Array = new ArrayList();
446 l_Array.add(p_Collections1);
447 l_Array.add(p_Collections2);
448 l_Array.add(p_Collections3);
449 l_Array.add(p_Collections4);
450
451 System.out.println("集合对象:" + l_Array);
452 //排序(升序)
453 Collections.sort(l_Array);
454 System.out.println("排序后,集合对象:" + l_Array);
455
456 //反转(执行排序后再执行反转 相当于降序)
457 Collections.reverse(l_Array);
458 System.out.println("反转后,集合对象:" + l_Array);
459
460
461 //混乱排序
462 Collections.shuffle(l_Array);//每次结果可能不一样
463 System.out.println("混乱排序后,集合对象:" + l_Array);
464
465 /**6.2 查找,替换操作**/
466 //查找 指定元素查找 返回索引
467 System.out.println("查找str_Collections元素的位置:" + Collections.binarySearch(l_Array,p_Collections1,null));
468
469 //交换 指定位置交换
470 System.out.println("交换前集合对象:" + l_Array);
471 Collections.swap(l_Array,1,2);
472 System.out.println("交换后集合对象:" + l_Array);
473
474 //替换 指定元素替换
475 Person p_Collections5 = new Person(5,"王");
476 System.out.println("替换前集合对象:" + l_Array);
477 Collections.replaceAll(l_Array,p_Collections4,p_Collections5);
478 System.out.println("替换后集合对象:" + l_Array);
479
480 /**6.3 同步控制**/
481 //使用该工具类的同步方法返回可同步的集合对象
482 Collection c=Collections.synchronizedCollection(new ArrayList());
483 List l=Collections.synchronizedList(new ArrayList());
484 Set s=Collections.synchronizedSet(new HashSet());
485 Map m=Collections.synchronizedMap(new HashMap());
486
487 /**6.4 总结**/
488 //1.Set类
489 //1.1 如果希望按照元素插入集合的顺序进行提取元素,用LinkedHashSet,它的元素按添加的顺序存储
490 //1.2 一般使用HashSet,因为它的效率比LinkedHashSet高
491 //1.3 TreeSet(集合元素有排序关系)
492 //2.List类
493 //2.1 ArrayList使用数组实现的动态扩展容量的list 定位查找操作效率快,不同步
494 //2.2 LinkedList链式实现的list,增加修改效率快,不同步
495 //2.3 Vector 同步版的ArrayList,因为同步,故效率不如ArrayList
496 //2.4 Stack继承Vector,模拟实现栈
497 //3.Map类
498 //3.1 键值对同List和Set不同
499 //3.2 HashMap:效率高
500 //3.3 TreeMap:排序性
501 //4.Collections类
502 //4.1 提供了许多静态的方法来管理集合
503 //5.Arrays类
504 //5.1 提供了对数组排序,查找,比较,填充元素的各种静态方法。
505
506 }
507
508
509 /*
510 * 抽取打印演示函数 用于打印演示功能提示
511 */
512 public static void showDemo(String demoStr){
513 System.out.println("演示:" + demoStr);
514 }
515
516 }