在我们常用的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. mysql库大小

    1.进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; 2.查询所有数据的大小: select concat(round(su ...

  2. Java 编辑tips

    1.      windows 安装 jdk配置环境 1) 下载jdk,正常安装结束,保存安装路径. 2)我的电脑—〉右键属性—〉高级系统设置—〉环境变量—〉添加系统变量 新建两个变量 JAVAHOM ...

  3. 洛谷P2925 [USACO08DEC]干草出售Hay For Sale

    题目描述 Farmer John suffered a terrible loss when giant Australian cockroaches ate the entirety of his ...

  4. 取出list的数组元素

    java中将list中的一维数组中的元素取出需要2步.第一步:获取list的迭代器,将数组从迭代器中遍历取出:第二部:对取出的数组进行遍历,取出数组中存储的元素.java的list集合中只能存储引用型 ...

  5. this的使用

    1.使用this调用本类中的属性 class Person{ private String name; private int age; public Person(String name,int a ...

  6. android jni

    1, java.lang.UnsatisfiedLinkError: Couldn't load xxxxx: findLibrary returned null 当 apk 是被放到 /system ...

  7. iOS应用开发最佳实践系列一:编写高质量的Objective-C代码

          本文由海水的味道编译整理,转载请注明译者和出处,请勿用于商业用途! 点标记语法 属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法. 良好的 ...

  8. Java初学(三)

    一.使用键盘录入数据 三步:1.导入包:import  java.util.Scanner; 2.创建键盘录入对象:Scanner sc=new  Scanner(System.in);   3.通过 ...

  9. Effective Java之最佳建议

    #Effective Java之最佳建议 此书中,目前给我帮助最大的两条建议是: - 检查参数的有效性 - 不要忽略异常 ###检查参数的有效性 对于这一条,使我感同身受的原因是:在Web项目中,前期 ...

  10. DEEP LEARNING WITH STRUCTURE

    DEEP LEARNING WITH STRUCTURE Charlie Tang is a PhD student in the Machine Learning group at the Univ ...