1. Map集合之基础增删查等功能
1 public class Demo1_Map { 2 3 /* 4 * Map集合是以键值对的形式存在,底层依赖的是set集合 5 * 6 * a. 添加功能 7 * V put(K key, V value) 8 * 如果键是第一次存入,则就直接存储元素,返回null (其实本质是和键存在是一样的,只是覆盖的null) 9 * 如果键不是第一次存入,就用值把以前的替换掉,返回以前的值 10 * b. 删除功能 11 * void clear() 移除所有的键值信息 12 * V remove(Object key) 删除指定键对应的元素值,并把值返回,当所传的键值不存在时就返回null 13 * c. 判断功能 14 * boolean containsKey(Object key) 判断集合中是否包含此键 15 * boolean containsValue(Object value) 判断集合是否包含指定的值 16 * boolean isEmpty() 判断集是否为空 17 * d. 获取功能 18 * Set<Map.Entry<K,V>> entrySet() 19 * V get(Object key) 根据键获取值 20 * Set<K> keySet() 获取集合中所有键的集合 21 * Collection<V> values() 获取集合中所有值的集合,返回一个Conllection 22 * e. 长度功能 23 * int size() 返回集合中所有键值对的个数 24 * 25 */ 26 public static void main(String[] args) { 27 28 //demo1(); 29 //demo2(); 30 //demo3(); 31 Map<String, Integer> map = new HashMap<>(); 32 Integer i1 = map.put("张三", 23); 33 Integer i2 = map.put("李四", 24); 34 Integer i3 = map.put("王五", 25); 35 Integer i4 = map.put("赵六", 26); 36 Integer i5 = map.put("张三", 26); 37 Set<Entry<String, Integer>> set = map.entrySet(); 38 System.out.println(set); //[李四=24, 张三=26, 王五=25, 赵六=26] 39 System.out.println(map.values()); //[24, 26, 25, 26] 40 41 } 42 43 /** 44 * 判断功能 45 */ 46 public static void demo3() { 47 Map<String, Integer> map = new HashMap<>(); 48 map.put("lisi", 24); 49 boolean b1 = map.containsKey("lisi"); 50 System.out.println(b1); //true 51 boolean b2 = map.containsValue(24) ; 52 System.out.println(b2); //true 53 } 54 55 /** 56 * 删除功能 57 */ 58 public static void demo2() { 59 Map<String, Integer> map = new HashMap<>(); 60 map.put("李四", 24); 61 Integer i = map.remove("张三"); 62 System.out.println(i); //null 63 Integer i1 = map.remove("李四"); 64 System.out.println(i1); //24 65 } 66 67 /** 68 * 添加功能 69 */ 70 public static void demo1() { 71 Map<String, Integer> map = new HashMap<>(); 72 Integer i1 = map.put("张三", 23); 73 Integer i2 = map.put("李四", 24); 74 Integer i3 = map.put("王五", 25); 75 Integer i4 = map.put("赵六", 26); 76 Integer i5 = map.put("张三", 26); 77 System.out.println(map); 78 System.out.println(i1); 79 System.out.println(i2); 80 System.out.println(i3); 81 System.out.println(i4); 82 System.out.println(i5); 83 } 84 85 }
2. 遍历Map集合
1 public class Demo2_Map { 2 3 /** 4 * @param args 5 * 遍历map集合 6 * 7 */ 8 public static void main(String[] args) { 9 10 Map<String, Integer> map = new HashMap<>(); 11 map.put("张三", 23); 12 map.put("李四", 24); 13 map.put("王五", 25); 14 map.put("赵六", 26); 15 16 /* 17 使用迭代器进行遍历Map集合 18 Set<String> set = map.keySet(); 19 Iterator<String> it = set.iterator(); 20 while (it.hasNext()) { 21 String key = it.next(); 22 System.out.println(key + "=" + map.get(key)); 23 }*/ 24 25 26 //使用增强for循环进行遍历Map集合 27 for (String string : map.keySet()) { 28 System.out.println(string + "=" + map.get(string)); 29 } 30 } 31 32 }
3. 通过Entry对Map集合进行遍历
1 public class Demo3_MapEntry { 2 3 /* 4 * 通过Entry对Map集合进行遍历 5 * Entry中后获取键的方法getKey() 和 获取值的方法 getValue() 6 */ 7 public static void main(String[] args) { 8 9 Map<String, Integer> map = new HashMap<>(); 10 map.put("张三", 23); 11 map.put("李四", 24); 12 map.put("王五", 25); 13 map.put("赵六", 26); 14 15 /* 16 *使用迭代器遍历集合 17 Set<Map.Entry<String, Integer>> entry = map.entrySet(); 18 Iterator<Map.Entry<String, Integer>> it = entry.iterator(); 19 while (it.hasNext()) { 20 Map.Entry<String, Integer> en = it.next(); 21 String key = en.getKey(); 22 Integer value = en.getValue(); 23 System.out.println(key + "=" + value); 24 }*/ 25 26 27 //通过增强for循环遍历集合 28 for (Map.Entry<String, Integer> en : map.entrySet()) { 29 System.out.println(en.getKey() + "=" + en.getValue()); 30 } 31 } 32 33 }
4. HashMap
1 public class Demo4_HashMap { 2 3 /* 4 * 向Map集合中存入自定义对象,将自定义对象作为集合的key 5 * 6 */ 7 public static void main(String[] args) { 8 Map<Student, String> map = new HashMap<>(); 9 map.put(new Student("张三",23), "北京"); 10 map.put(new Student("张三",23), "上海"); 11 map.put(new Student("李四",24), "广州"); 12 //重写hashCode() 和 equals() 方法前 {Student [name=张三, age=23]=北京, Student [name=李四, age=24]=广州, Student [name=张三, age=23]=上海} 13 //System.out.println(map); 14 //重写hashCode() 和 equals() 方法后 {Student [name=张三, age=23]=上海, Student [name=李四, age=24]=广州} 15 System.out.println(map); 16 17 } 18 19 }
5. LinkedHashMap 怎么存就怎么取
1 public class Demo5_LinkedHashMap { 2 3 /* 4 * LinkedHashMap 怎么存就怎么取 5 */ 6 public static void main(String[] args) { 7 8 LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>(); 9 lhm.put("张三", 23); 10 lhm.put("赵六", 26); 11 lhm.put("王五", 25); 12 lhm.put("李四", 24); 13 System.out.println(lhm); //{张三=23, 赵六=26, 王五=25, 李四=24} 14 } 15 16 }
6. TreeMap
1 public class Demo6_TreeMap { 2 3 /* 4 * 通TreeSet一样,也是有两种排序方式: 5 * 1. 使用对象自己进行排序 6 * 2. 使用比较器进行排序 7 */ 8 public static void main(String[] args) { 9 //demo2(); 10 //demo1(); 11 12 /* 13 * TreeMap传入Comparator对象,重写compare方法,先比较姓名,再比较年龄 14 */ 15 TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() { 16 17 @Override 18 public int compare(Student s1, Student s2) { 19 int num = s1.getName().compareTo(s2.getName()); 20 return num == 0 ? s1.getAge() - s2.getAge() : num; 21 } 22 }); 23 tm.put(new Student("张三",23), "北京"); 24 tm.put(new Student("李四", 24),"上海"); 25 tm.put(new Student("赵六", 26),"广州"); 26 tm.put(new Student("王五", 25),"深圳"); 27 System.out.println(tm); 28 //{Student [name=张三, age=23]=北京, Student [name=李四, age=24]=上海, Student [name=王五, age=25]=深圳, Student [name=赵六, age=26]=广州} 29 30 } 31 32 /** 33 * 普通的引用数据类型 34 */ 35 public static void demo2() { 36 TreeMap<String, Integer> ts = new TreeMap<>(); 37 ts.put("张三", 23); 38 ts.put("王五", 25); 39 ts.put("李四", 24); 40 ts.put("赵六", 26); 41 System.out.println(ts); //{张三=23, 李四=24, 王五=25, 赵六=26} 42 } 43 44 /** 45 * 自定义类实现Comparator接口,重写compareTo()方法,先比较年龄,后比较姓名 46 */ 47 public static void demo1() { 48 TreeMap<Student, String> tm = new TreeMap<>(); 49 tm.put(new Student("张三",23), "北京"); 50 tm.put(new Student("李四", 24),"上海"); 51 tm.put(new Student("赵六", 26),"广州"); 52 tm.put(new Student("王五", 25),"深圳"); 53 System.out.println(tm); 54 //当自定义类没有实现comparable时直接添加会报java.lang.ClassCastException: com.map.Student cannot be cast to java.lang.Comparable 55 //{Student [name=张三, age=23]=北京, Student [name=李四, age=24]=上海, Student [name=王五, age=25]=深圳, Student [name=赵六, age=26]=广州} 56 } 57 58 }
6.1 Student 自定义类
1 public class Student implements Comparable<Student> { 2 3 private String name; 4 private int age; 5 6 public Student() { 7 super(); 8 } 9 10 public Student(String name, int age) { 11 super(); 12 this.name = name; 13 this.age = age; 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public int getAge() { 25 return age; 26 } 27 28 public void setAge(int age) { 29 this.age = age; 30 } 31 32 @Override 33 public String toString() { 34 return "Student [name=" + name + ", age=" + age + "]"; 35 } 36 37 @Override 38 public int hashCode() { 39 final int prime = 31; 40 int result = 1; 41 result = prime * result + age; 42 result = prime * result + ((name == null) ? 0 : name.hashCode()); 43 return result; 44 } 45 46 @Override 47 public boolean equals(Object obj) { 48 if (this == obj) 49 return true; 50 if (obj == null) 51 return false; 52 if (getClass() != obj.getClass()) 53 return false; 54 Student other = (Student) obj; 55 if (age != other.age) 56 return false; 57 if (name == null) { 58 if (other.name != null) 59 return false; 60 } else if (!name.equals(other.name)) 61 return false; 62 return true; 63 } 64 65 @Override 66 public int compareTo(Student o) { 67 int num = this.age - o.age; //优先比对年龄 68 return num == 0 ? this.name.compareTo(o.name) : num; 69 } 70 71 }
7. HashMap和Hashtable的区别
* 共同点:
* 底层都是哈希算法,都是双列集合
* 区别:
* 1. HashMap是线程不安全的,效率高,JDK 1.2 版本
* Hashtable 是线程安全的,效率低,JDK 1.0版本
* 2. HashMap可以存储null键和null值
* Hashtable不可以
8. 集合练习之实现斗地主的获得牌、洗牌、发牌
* 需求:实现斗地主的洗牌、发牌、看牌(按所拿的牌排序显示)
* 分析:
* 1 获得一副牌
* 2 将牌存入HashMap集合中,将每张牌对应的索引存入list集合中
* 3 根据list集合中存的索引对牌进行洗牌
* 4 根据洗完牌的索引进行发牌
* 5 对每个人发的牌及底牌进行查看
1 public class Demo9_Doudizhu { 2 3 public static void main(String[] args) { 4 5 //获得一副牌并将牌存入HashMap集合,将索引存入list集合 6 String[] digit = {"2", "4", "5","6", "7","8","9","10","A","J","Q","k","3"}; 7 String[] color = {"红桃","方片","梅花","黑桃"}; 8 9 HashMap<Integer, String> hm = new HashMap<>(); 10 List<Integer> list = new ArrayList<>(); 11 int index = 0; 12 for(String s1 : digit) { 13 for(String s2 : color) { 14 hm.put(index, s2.concat(s1)); 15 list.add(index); 16 index++; 17 } 18 } 19 hm.put(index, "小王"); 20 list.add(index); 21 index++; 22 hm.put(index,"大王"); 23 list.add(index); 24 25 //洗牌 26 Collections.shuffle(list); 27 28 //发牌,创建相应的TreeSet集合用于存储发个每个人的牌和底牌 29 TreeSet<Integer> gaojin = new TreeSet<>(); 30 TreeSet<Integer> longwu = new TreeSet<>(); 31 TreeSet<Integer> me = new TreeSet<>(); 32 TreeSet<Integer> dipai = new TreeSet<>(); 33 for (Integer i : list) { 34 if(i >= list.size() - 3) { 35 dipai.add(list.get(i)); 36 }else if(i % 3 == 0) { 37 gaojin.add(list.get(i)); 38 }else if(i %3 == 1){ 39 longwu.add(list.get(i)); 40 }else { 41 me.add(list.get(i)); 42 } 43 } 44 45 //看牌 46 lookPoker(hm, gaojin, "高进"); 47 lookPoker(hm, longwu, "龙武"); 48 lookPoker(hm, me, "我"); 49 lookPoker(hm, dipai, "底牌"); 50 51 } 52 53 /** 54 * @param hm 55 * @param ts 56 * @param name 57 * 看牌函数 58 */ 59 public static void lookPoker(HashMap<Integer, String> hm, TreeSet<Integer> ts, String name) { 60 System.out.print(name + "的牌是:"); 61 for (Integer i : ts) { 62 System.out.print(hm.get(i) + " "); 63 } 64 System.out.println(); 65 } 66 67 }
9. 集合相关总结
* Collectiion
* List(存取有序,有索引,可以重复)
* ArrayList
* 底层是数组实现的,线程不安全,查找和修改快,增加和删除慢
* LinkedList
* 底层是链表实现的,线程不安全,增和删快,查和修改慢
* Vector
* 底层是数组实现的,线程是安全的,无论增删改查都满
* 如果查找和修改多,用ArrayList
* 如果增和删多,用LinkedList
* 如果都多,用ArrayList
* Set(存储无序,无索引,不可重复)
* HashSet
* 底层是哈希算法实现的
* LinkedHashSet
* 底层是链表实现的,但是也是可以保证元素唯一,和HashSet原理一样
* TreeSet
* 底层是二叉树算法实现的
* 一般在开发的时候不需要对存储的元素排序,所以在开发的一般用HashSet,HashSet的效率比较高
* TreeSet在面试的时候比较多,问你有几种排序方式,和几种排序方式的区别
* Map
* HashMap
* 底层是哈希算法,针对键
* LinkedHashMap
* 底层是链表,针对键
* TreeMap
* 底层是二叉树算法,针对键
* 开发中用HashMap比较多