在我们常用的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

 package net.zengzhiying.frame_on;

 import java.util.HashSet;
import java.util.Set; /*
* 学生类
*/ public class Student { public String id;
public String name;
public Set<Course> courses; //定义Set类型的集合用于存放所选课程 public Student(String id,String name){
this.id = id;
this.name = name;
this.courses = new HashSet<Course>(); //通过HashSet方法实例化Set类型的引用
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Student))
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}

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

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

 /*
* 课程类,规定课程结构,用于向集合中传入此类型的元素
*/ public class Course {
public String id;
public String name;
public Course(String id,String name){
//含参构造方法
this.id = id;
this.name = name;
} public Course(){
//无参构造器,为了子类初始化隐式构造方法
} }

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

 import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set; public class MapTest { /*
* 创建Map类型的属性,存放学生对象的引用
*/
public Map<String,Student> students; /*
* 构造方法初始化students属性
*/
public MapTest(){
this.students = new HashMap<String,Student>();
} /*
* 添加 学生
*/
public void testPut(){
Scanner console = new Scanner(System.in);
int i = 0;
while(i<3){
System.out.println("请输入学生的ID:");
String ID = console.next();
//判断ID是否已经占用,如果未占用则对象为空
Student st = students.get(ID);
if(st == null){
//输入学生的姓名
System.out.println("请输入学生的姓名:");
String name = console.next();
//创建学生对象
Student newStudent = new Student(ID,name);
//通过students的Put方法,添加学生id-学生对象映射
students.put(ID, newStudent); //将ID和对象传入,value必须是对象
System.out.println("成功添加学生:" + students.get(ID).name); //取出对象的姓名
i++;
}else{
System.out.println("该学生ID已被占用,请重新输入!");
continue;
}
}
} /*
* KeySet方法遍历Map的元素,这个也是无序的
*/
public void testKeySet(){
//通过KeySet方法返回Map中所有键的集合
Set<String> keyset = students.keySet();
//获得Map容量
System.out.println("总共有:" + students.size() + "个学生");
//遍历KeySet对象取得键,然后根据键取得value
for(String stuid:keyset){
Student st = students.get(stuid); //获得键所对应的对象
if(st != null){
System.out.println("学生姓名:" + st.name);
}
}
} /*
* 删除Map中的映射
*/
public void testRemove(){
Scanner console = new Scanner(System.in);
while(true){
System.out.println("请输入要删除的学生ID:");
//获取输入ID
String ID1 = console.next();
//判断ID映射是否存在
Student st = students.get(ID1);
if(st == null){
//不存在
System.out.println("输入的ID不存在,请重新输入!");
continue;
}else{ //存在,删除操作
students.remove(ID1);
System.out.println("删除成功!姓名:" + st.name);
break;
}
} } /*
* 通过EntrySet方法遍历Map中的元素
*/
public void testEntrySet(){
//返回的是键值对的集合
Set<Entry<String,Student>> entryset = students.entrySet(); //类型前后要完全一致
for(Entry<String,Student> entry:entryset){
System.out.println("取得键为:" + entry.getKey());
System.out.println("对应的学生对象的姓名为:" + entry.getValue().name); } } /*
* 修改映射中的元素,传入已经存在的key值修改
*/
public void testModify(){
Scanner console = new Scanner(System.in);
while(true){
System.out.println("请输入要修改的学生ID:");
//取得学生ID
String ID = console.next();
//根据ID查找是否有响应映射
Student student = students.get(ID);
if(student != null){
//不为空 修改操作
System.out.println("当前ID对应的学生为:" + student.name);
//提示输入新的姓名,修改已有映射
System.out.println("请输入新的学生姓名:");
String name = console.next();
//student.name = name; 因为是public所以这样直接赋值也是可以的
Student newStudent = new Student(ID,name);
students.put(ID, newStudent);
System.out.println("修改学生成功!");
break;
}else{
System.out.println("该ID不存在,请重新输入!");
continue;
}
}
} /*
* 测试Map中是否包含某个Key值或者某个Value值
*/
public void testContainsKeyOrValue(){
//用containsKey方法判断Map中是否包含某个Key值,用containsValue方法判断是否包含某个Value值 Scanner console = new Scanner(System.in); //通过输入ID判断
System.out.println("请输入要查询的ID:");
String ID = console.next();
System.out.println("您输入的学生ID为:" + ID + "在学生映射中是否存在:" + students.containsKey(ID));
if(students.containsKey(ID)){
System.out.println("对应的学生为:" + students.get(ID).name);
} //通过输入姓名进行查询
System.out.println("请输入要查询的学生姓名:");
String name = console.next();
//使用containsValue方法传入对象进行查询,id为任意值即可,通过name查询
//Map中的contains方法也会使用equals方法进行比对,所以在学生类中需要对该方法进行重写
if(students.containsValue(new Student("",name))){
System.out.println("在学生映射表中,包含学生:" + name);
}else{
System.out.println("要查找学生不存在!");
}
} public static void main(String[] args){
MapTest mt = new MapTest();
mt.testPut();
mt.testKeySet();
// mt.testRemove();
// mt.testEntrySet();
// mt.testModify();
// mt.testEntrySet(); mt.testContainsKeyOrValue();
}
}

  在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接口是两个不同的集合根接口,提供的不同的对象存放形式,另外还提供了很多操作方法,对开发带来很大的方便,这些知识点也需要我们自己多总结多敲代码,才可以熟练应用

Java集合框架中Map接口的使用的更多相关文章

  1. Java集合框架之Map接口浅析

    Java集合框架之Map接口浅析 一.Map接口综述: 1.1java.util.Map<k, v>简介 位于java.util包下的Map接口,是Java集合框架的重要成员,它是和Col ...

  2. Java集合框架中List接口的简单使用

    Java集合框架可以简单的理解为一种放置对象的容器,和数学中的集合概念类似,Java中的集合可以存放一系列对象的引用,也可以看做是数组的提升,Java集合类是一种工具类,只有相同类型的对象引用才可以放 ...

  3. 第19章 集合框架(3)-Map接口

    第19章 集合框架(3)-Map接口 1.Map接口概述 Map是一种映射关系,那么什么是映射关系呢? 映射的数学解释 设A,B是两个非空集合,如果存在一个法则,使得对A中的每一个元素a,按法则f,在 ...

  4. 【JAVA集合框架之Map】

    一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...

  5. Java集合框架之Collection接口

    Java是一门面向对象的语言,那么我们写程序的时候最经常操作的便是对象了,为此,Java提供了一些专门用来处理对象的类库,这些类库的集合我们称之为集合框架.Java集合工具包位于Java.util包下 ...

  6. Java集合框架之四大接口、常用实现类

    Java集合框架 <Java集合框架的四大接口> Collection:存储无序的.不唯一的数据:其下有List和Set两大接口. List:存储有序的.不唯一的数据: Set:存储无序的 ...

  7. Java集合框架之Set接口浅析

    Java集合框架之Set接口浅析 一.java.util.Set接口综述: 这里只对Set接口做一简单综述,其具体实现类的分析,朋友们可关注我后续的博文 1.1Set接口简介 java.util.se ...

  8. java 集合框架(二)Iterable接口

    Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...

  9. 第49节:Java集合框架中底层文档的List与Set

    Java集合框架中的List与Set // 简书作者:达叔小生 Collection -> Set 无序不重复 -> 无序HashSet,需要排序TreeSet -> List 有序 ...

随机推荐

  1. 项目跑起来之后,一会儿后台就会报错Illegal access: this web application instance has been stopped already. Could not load [com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask]. The following stack trace

    一月 24, 2016 6:42:54 下午 org.apache.catalina.loader.WebappClassLoaderBase checkStateForResourceLoading ...

  2. @RestController注解下返回到jsp视图页面(转)(转)

    这个问题我也遇到过,下面的方法可以试试 蓝萝卜blu @RestController注解下返回到jsp视图页面 spring4.1中添加了@RestController注解很方便,集成了@Respon ...

  3. RegexBuddy正则表达式工具

    RegexBuddy非常的好用,而且还能生成.net的代码. 我们在使用正则匹配时,毕竟.net提供的方法中,对于多行匹配就不能用单纯的正则去实现,而我们需要把它转换成相应的类库方法进行实现. 那么R ...

  4. UVa 437 The Tower of Babylon

    Description   Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details of ...

  5. Ext comboBox的remote和local的区别

    remote模式下不能使用模糊查询的功能 而local模式下可以实现模糊查询的功能 如果非要实现模糊查询的功能,最好就是提前把数据查询出来,缓存到本地,然后再用local模式 且,改个属性,改成可编辑 ...

  6. PHP 7.1 新特性一览

    可空类型主要用于参数类型声明和函数返回值声明.主要的两种形式如下:<?phpfunction answer(): ?int  {   return null; //ok}function ans ...

  7. cf340 C. Watering Flowers

    C. Watering Flowers time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  8. Laravel教程 二:路由,视图,控制器工作流程

    Laravel教程 二:路由,视图,控制器工作流程 此文章为原创文章,未经同意,禁止转载. View Controller 上一篇教程我们走了那么长的路,终于把Laravel安装好了,这一篇教程我们就 ...

  9. linux set ff命令

    在windows下写的代码传到linux上无法直接运行时 vi 文件名 :set ff=unix :wq 这样就可以运行了

  10. linux init.d脚本编写模板

    #!/bin/bash ### BEGIN INIT INFO # # Provides: location_server # Required-Start: $local_fs $remote_fs ...