zoukankan      html  css  js  c++  java
  • 黑马程序员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 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集合中的数据打印。

       

  • 相关阅读:
    asp.net与javascript问题
    动态加载用户控件
    ASP.NET中实现模版的动态加载
    一个简单的购物车
    给图片加上水印效果
    用存储过程自定义分页
    上传图片及显示图片
    sql server图片的保存和读取
    Legato Single Server SertupFor RMAN
    确定裸设备上控制文件的大小
  • 原文地址:https://www.cnblogs.com/jbelial/p/2991216.html
Copyright © 2011-2022 走看看