• Java集合框架中Map接口的使用


      在我们常用的Java集合框架接口中,除了前面说过的Collection接口以及他的根接口List接口和Set接口的使用,Map接口也是一个经常使用的接口,和Collection接口不同,Map接口并不是线性的存放对象的引用,Map接口提供了一种映射关系,所有的元素都是以键值对(Entry类型对象实例)的方式存储的,所以能够根据key快速查找value,key是映射关系的索引,value是key所指向的对象,注意,这里的value不是一个数值,而是一个对象的引用,Java集合框架的元素均是指对象!

      Map中的key值不可重复,value值可以重复,每个key值只能映射到一个value对象;

      Map支持泛型,形式如:<K,V>分别代表Key值的存放的对象类型和value值的对象类型;

      使用Map接口,和前面一样,不能直接使用,HashMap是Map接口的重要实现类,基于哈希表实现,既然是基于哈希算法,那么HashMap的Entry对象是无序排列的;

      key和value的值都可以为null,因为key值是唯一的,所以只能有一个key值为null

      

      在前面的Collection接口中,使用List存放了课程对象,现在利用一个简单的例子,使用Map存放学生对象,一个学生属性就包括:id,姓名,所选课程

      学生类:Student.java

     1 package net.zengzhiying.frame_on;
     2 
     3 import java.util.HashSet;
     4 import java.util.Set;
     5 
     6 /*
     7  * 学生类
     8  */
     9 
    10 public class Student {
    11 
    12     public String id;
    13     public String name;
    14     public Set<Course> courses;    //定义Set类型的集合用于存放所选课程
    15     
    16     public Student(String id,String name){
    17         this.id = id;
    18         this.name = name;
    19         this.courses = new HashSet<Course>();    //通过HashSet方法实例化Set类型的引用
    20     }
    21 
    22     @Override
    23     public boolean equals(Object obj) {
    24         if (this == obj)
    25             return true;
    26         if (obj == null)
    27             return false;
    28         if (!(obj instanceof Student))
    29             return false;
    30         Student other = (Student) obj;
    31         if (name == null) {
    32             if (other.name != null)
    33                 return false;
    34         } else if (!name.equals(other.name))
    35             return false;
    36         return true;
    37     }
    38 }

      学生类代码很简单,主要是课程类型的属性,使用Set接口进行存放,并且规定了课程类型的泛型

      既然需要课程,那么课程类代码需要重复一下:Course.java

     1 /*
     2  * 课程类,规定课程结构,用于向集合中传入此类型的元素
     3  */
     4 
     5 public class Course {
     6     public String id;
     7     public String name;
     8     public Course(String id,String name){
     9         //含参构造方法
    10         this.id = id;
    11         this.name = name;
    12     }
    13     
    14     public Course(){
    15         //无参构造器,为了子类初始化隐式构造方法
    16     }
    17 
    18 }

      接下来需要使用Map接口,进行一系列操作,代码在MapTest.java中

      1 import java.util.HashMap;
      2 import java.util.Map;
      3 import java.util.Map.Entry;
      4 import java.util.Scanner;
      5 import java.util.Set;
      6 
      7 
      8 public class MapTest {
      9     
     10     /*
     11      * 创建Map类型的属性,存放学生对象的引用
     12      */
     13     public Map<String,Student> students;
     14     
     15     /*
     16      * 构造方法初始化students属性
     17      */
     18     public MapTest(){
     19         this.students = new HashMap<String,Student>();
     20     }
     21     
     22     /*
     23      * 添加 学生
     24      */
     25     public void testPut(){
     26         Scanner console = new Scanner(System.in);
     27         int i = 0;
     28         while(i<3){
     29             System.out.println("请输入学生的ID:");
     30             String ID = console.next();
     31             //判断ID是否已经占用,如果未占用则对象为空
     32             Student st = students.get(ID);
     33             if(st == null){
     34                 //输入学生的姓名
     35                 System.out.println("请输入学生的姓名:");
     36                 String name = console.next();
     37                 //创建学生对象
     38                 Student newStudent = new Student(ID,name);
     39                 //通过students的Put方法,添加学生id-学生对象映射
     40                 students.put(ID, newStudent);    //将ID和对象传入,value必须是对象
     41                 System.out.println("成功添加学生:" + students.get(ID).name);    //取出对象的姓名
     42                 i++;
     43             }else{
     44                 System.out.println("该学生ID已被占用,请重新输入!");
     45                 continue;
     46             }
     47         }
     48     }
     49     
     50     /*
     51      * KeySet方法遍历Map的元素,这个也是无序的
     52      */
     53     public void testKeySet(){
     54         //通过KeySet方法返回Map中所有键的集合
     55         Set<String> keyset = students.keySet();
     56         //获得Map容量
     57         System.out.println("总共有:" + students.size() + "个学生");
     58         //遍历KeySet对象取得键,然后根据键取得value
     59         for(String stuid:keyset){
     60             Student st = students.get(stuid);    //获得键所对应的对象
     61             if(st != null){
     62                 System.out.println("学生姓名:" + st.name);
     63             }
     64         }
     65     }
     66     
     67     /*
     68      * 删除Map中的映射
     69      */
     70     public void testRemove(){
     71         Scanner console = new Scanner(System.in);
     72         while(true){
     73             System.out.println("请输入要删除的学生ID:");
     74             //获取输入ID
     75             String ID1 = console.next();
     76             //判断ID映射是否存在
     77             Student st = students.get(ID1);
     78             if(st == null){
     79                 //不存在
     80                 System.out.println("输入的ID不存在,请重新输入!");
     81                 continue;
     82             }else{
     83                 
     84                 //存在,删除操作
     85                 students.remove(ID1);
     86                 System.out.println("删除成功!姓名:" + st.name);
     87                 break;
     88             }
     89         }
     90         
     91     }
     92     
     93     /*
     94      * 通过EntrySet方法遍历Map中的元素
     95      */
     96     public void testEntrySet(){
     97         //返回的是键值对的集合
     98         Set<Entry<String,Student>> entryset = students.entrySet();    //类型前后要完全一致
     99         for(Entry<String,Student> entry:entryset){
    100             System.out.println("取得键为:" + entry.getKey());
    101             System.out.println("对应的学生对象的姓名为:" + entry.getValue().name);
    102             
    103         }
    104         
    105     }
    106     
    107     /*
    108      * 修改映射中的元素,传入已经存在的key值修改
    109      */
    110     public void testModify(){
    111         Scanner console = new Scanner(System.in);
    112         while(true){
    113             System.out.println("请输入要修改的学生ID:");
    114             //取得学生ID
    115             String ID = console.next();
    116             //根据ID查找是否有响应映射
    117             Student student = students.get(ID);
    118             if(student != null){
    119                 //不为空 修改操作
    120                 System.out.println("当前ID对应的学生为:" + student.name);
    121                 //提示输入新的姓名,修改已有映射
    122                 System.out.println("请输入新的学生姓名:");
    123                 String name = console.next();
    124                 //student.name = name;    因为是public所以这样直接赋值也是可以的
    125                 Student newStudent = new Student(ID,name);
    126                 students.put(ID, newStudent);
    127                 System.out.println("修改学生成功!");
    128                 break;
    129             }else{
    130                 System.out.println("该ID不存在,请重新输入!");
    131                 continue;
    132             }
    133         }
    134     }
    135     
    136     /*
    137      * 测试Map中是否包含某个Key值或者某个Value值
    138      */
    139     public void testContainsKeyOrValue(){
    140         //用containsKey方法判断Map中是否包含某个Key值,用containsValue方法判断是否包含某个Value值
    141         
    142         Scanner console = new Scanner(System.in);
    143         
    144         //通过输入ID判断
    145         System.out.println("请输入要查询的ID:");
    146         String ID = console.next();
    147         System.out.println("您输入的学生ID为:" + ID + "在学生映射中是否存在:" + students.containsKey(ID));
    148         if(students.containsKey(ID)){
    149             System.out.println("对应的学生为:" + students.get(ID).name);
    150         }
    151         
    152         //通过输入姓名进行查询
    153         System.out.println("请输入要查询的学生姓名:");
    154         String name = console.next();
    155         //使用containsValue方法传入对象进行查询,id为任意值即可,通过name查询
    156         //Map中的contains方法也会使用equals方法进行比对,所以在学生类中需要对该方法进行重写
    157         if(students.containsValue(new Student("",name))){
    158             System.out.println("在学生映射表中,包含学生:" + name);
    159         }else{
    160             System.out.println("要查找学生不存在!");
    161         }
    162     }
    163     
    164     
    165     public static void main(String[] args){
    166         MapTest mt = new MapTest();
    167         mt.testPut();
    168         mt.testKeySet();
    169 //        mt.testRemove();
    170 //        mt.testEntrySet();
    171 //        mt.testModify();
    172 //        mt.testEntrySet();
    173         
    174         
    175         mt.testContainsKeyOrValue();
    176     }
    177 }

      在MapTest类中,对Map接口进行了实现,插入数据,遍历数据,修改数据,删除数组最后利用containsKey方法和containsValue方法进行了元素的查找,最核心的操作也就是这些,main方法中为了便于测试,后面注释了一些语句,实际情况根据需要调用即可

      首先,插入学生对象的时候,使用了手动输入插入,系统判断对象ID是否已经存在,如果不存在则对象值为null此时进行插入,添加Map映射对象,使用put方法,获取仍然使用get(key)的形式进行查询

      使用keySet方法可以返回Map中所有的键的集合,然后可以根据键取得value,实现Map集合的遍历;

      使用entrySet方法可以返回Map中所有entry键值对的集合,同样可以方便的遍历所有元素;

      通过remove(key)方法可以删除key键对应的映射

      修改的时候通过put方法传入新的value可以实现修改,此处注意,因为student中的属性全部都是公有所以通过student.name = newname;这样直接修改值也是可以的,因为此时查询到的对象正好是students的Map集合中所存在的对象,所以修改的时候,修改的也一定是该对象的值,更好的方法是通过类中自定义的setter方法进行修改,不一定必须用put方法新创建一个对象进行传入,只要知道原理,上述方法更改都是可以的

      最后是利用containsKey和containsValue方法进行查询,通过ID查询是很简单的,但是通过学生姓名进行查询,实际上先需要传入value查询,对于value的对象,应该包含id与name,所以只要containsValue方法之比较name而忽略ID即可,containsValue方法对于传入的对象也是使用equals方法进行比较的,前面我们说过equals方法默认比较的是对象引用的内存地址,并不是比较对象的属性值,这个时候我们的方法很明确,就是在Student类中重写equals方法,实现我们想要的功能,代码上面有,就是比较两个对象的name值,只要name值相等,就认为查询到了该对象,然后输出相应的信息即可,在现实应用中,其实也是这样,我们是着重比较某个值是否相同,而不是其他,这样就能实现通过value查询,确切来说是通过重写equals方法实现了通过对象中的任一元素可以进行查询,

      以上就是Map接口的简单应用,Map接口和Collection接口是两个不同的集合根接口,提供的不同的对象存放形式,另外还提供了很多操作方法,对开发带来很大的方便,这些知识点也需要我们自己多总结多敲代码,才可以熟练应用

  • 相关阅读:
    HDFS 常用Shell命令
    Hadoop单点伪分布模式安装
    部署及更新应用
    Linux云服务器下Tomcat部署超详细
    Android基础知识总结系列(一)——Android 系统框架
    Linux下的暴力密码在线破解工具Hydra安装及其组件安装-使用
    Luogu1501 Tree Ⅱ
    C#中Dictionary的用法(转)
    Lua协程
    SSH Secure Shell Client
  • 原文地址:https://www.cnblogs.com/freeweb/p/4846401.html
Copyright © 2020-2023  润新知