黑马程序员-JAVA基础-Java 集合之Map 接口

java

  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 Writer

2 {

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 Writer

2 {

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 Writer

2 {

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 Student  

2 {

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

回到顶部