黑马程序员-JAVA基础-Java 集合之Map 接口
Map 用于保存具有映射关系的数据,因此Map 集合里保存者两组值,一组值用于保存Map 里的Key ,另一组值用于保存Map 里的Value ,其中key 和 value 都是可以是任何引用类型的数据。
注意:Map 的key 不允许重复,且通过指定的key,总能找到唯一的、确定的value。即key 和 value 之间存在单向一对一关系。
Map 接口的经常用到的实现类:HashMap、Hashtable和TreeMap。
一.Map 集合中的共性方法
1、添加:
> V put(K key, V value) : 添加一个key-value 对,如果当前Map中已有一个与该key 相等的key-value 对,则新的key-value 对会覆盖原来的,并返回原来的value。
> void putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中。
2、删除:
> void clear() : 从此映射中移除所有映射关系 。
> V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除 , 并返回 value 。
3、判断:
> boolean containsKey(Object key) :如果Map 中包含指定key ,则返回 true。
> boolean containsValue(Object value) : 如果Map 中包含一个或多个value , 则返回true。
> boolean isEmpty() : 如果Map 为空,则返回true 。
4、获取:
> V get(Object key) 返回key 对应的value , 如果没有则返回null 。
> int size() 返回Map 中 key-value 对的个数。
> Collection values() : 返回该Map 里所有value 组成的Collection 。
1 public class MapDemo {2 public static void main(String[] args)
3 {
4 // 定义个 HashMap 集合, key 和 value的类型都为String。
5 Map<String, String> map = new HashMap<String, String>() ;
6 // 添加元素
7 map.put("诛仙", "萧鼎") ;
8 map.put("笑傲江湖", "金庸") ;
9 map.put("神雕侠侣", "金庸") ;
10 map.put("陆小凤传奇", "古龙") ;
11 System.out.println(map);
12 System.out.println(map.put("笑傲江湖", "金——庸"));
13 System.out.println(map);
14 // 删除元素
15 System.out.println(map.remove("笑傲江湖") );
16 System.out.println(map);
17 // 获取元素
18 System.out.println(map.get("诛仙"));
19 // 获取元素个数
20 System.out.println(map.size());
21 // 判断
22 System.out.println(map.containsKey("诛仙"));
23 }
24 }
二.HashMap 和 Hashtable 实现类:
HashMap 和 Hashtable 它们之间的关系完全类似于 ArrayList 和 Vector 的关系。它们两个底层都是哈希表数据结构,两者的区别:
1、Hashtable 不可以存入null 键和null 值;但是HashMap 可以存入null 键和null 值。
2、hashtable 是线程安全Map 实现;但HashMap 是线程不安全的实现类。所以HashMap 性能比较高点。
1 public class HashMapDemo {2 public static void main(String[] args)
3 {
4 Map<String,String> hash = new HashMap<String, String>() ;
5
6 // 给HashMap 集合存入null键或者null值
7 hash.put("111", null) ;
8 hash.put(null, "1112") ;
9 // 取出的结果为 1112
10 System.out.println(hash.get(null));
11 Map<String,String> table = new Hashtable<String, String>() ;
12 // 下面的代码会出现运行异常:NullPointerException
13 table.put("111", null) ;
14 table.put(null, "1112") ;
15 System.out.println(table.get(null));
16 }
17 }
类似HashSet , HashMap 和 Hashtable 也不能保证其中的key-value 对的顺序。它们判断两个key的标准也是:
1、先判断两个key 的hashCode 值是不是相等,
2、如果相等则再调用equals方法的返回值来进行判断。返回true 表示两个key值一样;返回false 表示不一样。
1 class Writer2 {
3 private String name ;
4 public Writer(String name)
5 {
6 this.name = name ;
7 }
8 // get方法
9 public String getName()
10 {
11 return name ;
12 }
13 // 重写hashCode方法
14 public int hashCode()
15 {
16 System.out.println(this.name+"---------hashCode--------");
17 return this.name.hashCode() ;
18 }
19 // 重写equals方法
20 public boolean equals(Object o)
21 {
22 if (!(o instanceof Writer))
23 throw new RuntimeException() ;
24 Writer w = (Writer) o ;
25 System.out.println(name+"---------equals--------"+w.name);
26 return this.name.equals(w.getName()) ;
27 }
28 }
29 public class MapDemo1 {
30 public static void main(String[] args)
31 {
32 // 定义个 HashMap 集合, key 的存储的数据类型为Writer, value的类型为String。
33 Map<Writer,String> writerMap = new HashMap<Writer,String>() ;
34
35 // 添加元素:
36 writerMap.put(new Writer("金庸"), "笑傲江湖") ;
37 writerMap.put(new Writer("萧鼎"), "诛仙") ;
38 writerMap.put(new Writer("金庸"), "笑傲江湖") ;
39
40 System.out.println(writerMap);
41 }
42 }
三.TreeMap 实现类
TreeMap 实现的的底层是二叉树的数据结构。线程是不同步的,其特点是:TreeMap 会对集合中所有 key 进行排序;也有两种排序方式:
1、自然排序: TreeMap 的所有key 必须实现Comparable 接口,而且所有key 必须是同一类对象。
2、制定排序: 编写比较器。在创建集合容器时将比较器传入至集合构造器。
1 //创建Books类并且 实现Comparable 接口2 //如果Books的名字和编号都相同则表示同一本书
3 class Books implements Comparable<Books>
4 {
5 private String name ;
6 private String id ;
7 public Books(String name , String id )
8 {
9 this.name = name ;
10 this.id = id ;
11 }
12 // get方法
13 public String getName()
14 {
15 return name ;
16 }
17 public String getId()
18 {
19 return id ;
20 }
21
22 // 覆盖compareTo 方法
23 public int compareTo(Books b)
24 {
25 int num = this.id.compareTo(b.getId()) ;
26 if (num == 0)
27 {
28 return this.name.compareTo(b.getName()) ;
29 }
30 return num ;
31 }
32 // 重写hashCode 方法
33 public int hashCode()
34 {
35 return this.name.hashCode()+ this.id.hashCode() ;
36 }
37 // 重写equals 方法
38 public boolean equals(Object o)
39 {
40 if (!(o instanceof Books))
41 throw new RuntimeException() ;
42 Books b = (Books) o ;
43 return this.name.equals(b.getName())&& this.id.equals(b.getId()) ;
44 }
45 }
46 public class TreeMapDemo {
47 public static void main(String[] args)
48 {
49 Map<Books,String> bookMap = new TreeMap<Books, String> () ;
50
51 bookMap.put(new Books("笑傲江湖","000001"), "金庸") ;
52 bookMap.put(new Books("笑傲江湖","000002"), "金庸") ;
53 bookMap.put(new Books("笑傲江湖","000004"), "金庸") ;
54 bookMap.put(new Books("笑傲江湖","000003"), "金庸") ;
55 bookMap.put(new Books("神雕侠侣","000001"), "金庸") ;
56
57 // 取出方式:entry()
58 Set<Entry<Books, String>> bookEntry = bookMap.entrySet() ;
59 Iterator<Map.Entry<Books, String>> itEntry = bookEntry.iterator() ;
60 while(itEntry.hasNext())
61 {
62 Map.Entry<Books, String> entry = itEntry.next() ;
63 System.out.println("name:" + entry.getKey().getName() +
64 " id:" + entry.getKey().getId() +
65 " 作者: " + entry.getValue());
66 }
67 }
68 }
四.Map 集合的两种取出方式:
因为 Map集合中没有Iterator 迭代器,所以如果想将Map 集合中的元素遍历以便就要能用到下面两个方法:
1、Set<Map.Entry<K,V>> entrySet() :返回此映射中包含的映射关系的 Set 视图。映射关系为 Map.Entry<K,V>类型 ;
2、Set<K> keySet():将Map 中所有的键存入到Set集合中 ;
原理是:将Map 集合中的元素取出保存到Set 集合中,再根据Set 集合中的Iterator 迭代器取出。
4.1 、 entrySet()
Map.Entry<K,V> 为一个接口(Map 接口中的内部类),其用法和 Iterator 接口类似。该接口包含如下方法
> boolean equals(Object o) : 比较指定对象与此项的相等性。
> K getKey() : 返回与此项对应的键。
> V getValue() : 返回与此项对应的值。
> int hashCode() : 返回此映射项的哈希码值。
> V setValue(V value) : 用指定的值替换与此项对应的值 。
步骤如下:
1、先获取Map 集合中的key-value 对的关系Set<Map.Entry<K,V>> 集合。
2、获取 Set 集合的迭代器。
3、遍历取出。
1 class Writer2 {
3 private String name ;
4 public Writer(String name)
5 {
6 this.name = name ;
7 }
8 // get方法
9 public String getName()
10 {
11 return name ;
12 }
13 // 重写hashCode方法
14 public int hashCode()
15 {
16 return this.name.hashCode() ;
17 }
18 // 重写equals方法
19 public boolean equals(Object o)
20 {
21 if (!(o instanceof Writer))
22 throw new RuntimeException() ;
23 Writer w = (Writer) o ;
24 return this.name.equals(w.getName()) ;
25 }
26 }
27 public class MapDemo1 {
28 public static void main(String[] args)
29 {
30 // 定义个 HashMap 集合, key 的存储的数据类型为Writer, value的类型为String。
31 Map<Writer,String> writerMap = new HashMap<Writer,String>() ;
32
33 // 添加元素:
34 writerMap.put(new Writer("金庸"), "笑傲江湖") ;
35 writerMap.put(new Writer("萧鼎"), "诛仙") ;
36 writerMap.put(new Writer("古龙"), "流星蝴蝶剑") ;
37
38 // System.out.println(writerMap);
39 // 将Map 元素取出存入Set 集合,指定该Set集合只能存入MapEntry<>数据类型。
40 Set<Map.Entry<Writer, String>> setMap = writerMap.entrySet() ;
41 // 建立迭代器
42 Iterator<Map.Entry<Writer,String>> it = setMap.iterator() ;
43 while(it.hasNext())
44 {
45 // 取出key-value 对
46 Map.Entry<Writer, String> entry = it.next() ;
47 System.out.println("key:"+ entry.getKey().getName()+
48 "value:"+ entry.getValue());
49 }
50 }
51 }
4.2 keySet() :
步骤:
1、先获取Map集合的所有键的Set集合。
2、获取Set集合的迭代器。
3、遍历。通过Mao集合get方法获取其对应的值。
1 class Writer2 {
3 private String name ;
4 public Writer(String name)
5 {
6 this.name = name ;
7 }
8 // get方法
9 public String getName()
10 {
11 return name ;
12 }
13 // 重写hashCode方法
14 public int hashCode()
15 {
16 return this.name.hashCode() ;
17 }
18 // 重写equals方法
19 public boolean equals(Object o)
20 {
21 if (!(o instanceof Writer))
22 throw new RuntimeException() ;
23 Writer w = (Writer) o ;
24 return this.name.equals(w.getName()) ;
25 }
26 }
27 public class MapDemo1 {
28 public static void main(String[] args)
29 {
30 // 定义个 HashMap 集合, key 的存储的数据类型为Writer, value的类型为String。
31 Map<Writer,String> writerMap = new HashMap<Writer,String>() ;
32
33 // 添加元素:
34 writerMap.put(new Writer("金庸"), "笑傲江湖") ;
35 writerMap.put(new Writer("萧鼎"), "诛仙") ;
36 writerMap.put(new Writer("古龙"), "流星蝴蝶剑") ;
37 // 取出key ,存入Set 集合
38 Set<Writer> setMap = writerMap.keySet() ;
39 // 获取Set集合迭代器
40 Iterator<Writer> it = setMap.iterator() ;
41 while(it.hasNext())
42 {
43 Writer w = it.next() ;
44 System.out.println("key:"+w.getName() +
45 "value:" + writerMap.get(w));
46 }
47
48 }
49 }
五.Map 集合练习:
1、要求:
每个学生都有一个归属地。
学生Student , 地址 String
学生的属性:姓名、年龄
注意:姓名和年龄相同的视为同一个学生。
1 class Student2 {
3 private String name ;
4 private int age ;
5 public Student(String name , int age)
6 {
7 this.name = name ;
8 this.age = age ;
9 }
10 // get方法:
11 public String getName()
12 {
13 return name ;
14 }
15 public int getAge()
16 {
17 return age ;
18 }
19 // instanceof 判断函数:
20 private Student myIstanceof(Object o)
21 {
22 if (!(o instanceof Student))
23 throw new RuntimeException() ;
24 return (Student) o ;
25 }
26 // 重写equals 方法
27 public boolean equals(Object o)
28 {
29 Student stu = myIstanceof(o);
30 return this.name.equals(stu.getName()) && this.age == stu.getAge() ;
31 }
32 // 重写hashCode方法
33 public int hashCode()
34 {
35 return name.hashCode()+age*39 ;
36 }
37 }
38 public class Demo {
39 public static void main(String[] args)
40 {
41 // 创建Map 类:
42 Map<Student,String> stuMap = new HashMap<Student, String>() ;
43
44 stuMap.put(new Student("lisi002" , 11), "北京" ) ;
45 stuMap.put(new Student("lisi001" , 14), "上海" ) ;
46 stuMap.put(new Student("lisi005" , 10), "天津" ) ;
47 stuMap.put(new Student("lisi005" , 19), "天津" ) ;
48 stuMap.put(new Student("lisi001" , 19), "长沙" ) ;
49
50 stuMap.put(new Student("lisi001" , 14), "北京" ) ;
51
52 // 第一种取出方式:keySet()
53 Set<Student> stuSet = stuMap.keySet() ;
54 Iterator<Student> it = stuSet.iterator() ;
55 while(it.hasNext())
56 {
57 Student stu = it.next() ;
58 System.out.println("name:"+stu.getName()
59 +" age:"+stu.getAge() + " 地址:" + stuMap.get(stu));
60 }
61 System.out.println("------我是分割线------");
62 // 第二种取出方式:entry()
63 Set<Map.Entry<Student, String>> stuEntry = stuMap.entrySet() ;
64 Iterator<Map.Entry<Student, String>> itEntry = stuEntry.iterator() ;
65 while(itEntry.hasNext())
66 {
67 Map.Entry<Student, String> entry = itEntry.next() ;
68 System.out.println("name:" + entry.getKey().getName() +
69 " age:" + entry.getKey().getAge() +
70 " 地址: " + entry.getValue());
71 }
72 }
73 }
2、字母出现的次数:
输入一段字符串,获取该字符串中的字母出现的次数。
希望打印结果:
字母1(次数)字母2(次数)....
通过结果发现,每一个字母都有对应的次数,说明字母和次数间有对应关系。
1 public class TreeMapTest {2 public static void main(String[] args)
3 {
4 Scanner scan = new Scanner(System.in) ;
5 String str = scan.nextLine() ;
6 Map<Character,Integer> CNTree = new TreeMap<Character, Integer>() ;
7 // 存入Map集合。
8 char[] chs = str.toCharArray() ;
9 for (int i = 0 ; i < chs.length ; i ++)
10 {
11 Integer values = CNTree.get(chs[i]) ;
12
13 if (values == null )
14 CNTree.put(chs[i], 1) ;
15 else
16 CNTree.put(chs[i], values+1) ;
17 }
18
19 // 遍历Map集合
20 Set<Character> charSet = CNTree.keySet() ;
21 Iterator<Character> it = charSet.iterator() ;
22 while(it.hasNext())
23 {
24 Character character = it.next() ;
25 System.out.println(character.charValue() +" "+ CNTree.get(character));
26 }
27 }
28 }
思路:
1、将字符串转换成字符数组(因为要对每一个字母进行操作)。
2、定义一个map集合,使用TreeMap 集合。
3、遍历字符数组:
a、将每一个字母作为键去查Map集合。
b、如果返回null,将该字母和1存入Map集合中。
c、如果返回不是null,则自增后,存入Map集合中。
4、将Map集合中的数据打印。
以上是 黑马程序员-JAVA基础-Java 集合之Map 接口 的全部内容, 来源链接: utcz.com/z/389656.html