《映射表》学习


映射是指两个集合之间的元素的相互对应关系。通俗地说,就是一个元素对应另外一个元素。比如有一个姓名的集合 {"Tom", "Jone", "Mary"},班级集合 {1,2}。姓名与班级之间可以有如下的映射关系:

class ("Tom")=1,class ("Jone")=2,class("Mary")=1

我们称其中的姓名集合为关键字集合(key),班级集合为值集合(value)

在 C++ 中我们常用的映射是map,在 Java 中常用映射是HashMap

引用库

在 C++ 中map的实现在一个头文件中,在代码开头引入这个头文件,并且加上一句using namespace std。

#include 

using namespace std;

在 Java 中HasMap在java.util.HashMap包里面实现。通过import的方式引入。

import java.util.HashMap;

构造一个映射

现在我们来构造一个映射。

在 C++ 中,我们构造一个map的语句为:map m;。这样我们定义了一个名为m的从T1类型T2类型的映射。初始的时候m是空映射。

在 Java 中,我们通过HashMap map = new HashMap()构造一个从T1类型T2类型的映射的HashMap对象。初始的时候map是空映射。

确认懂了再继续喔

插入映射

在 C++ 中通过insert()方法向集合中 插入一个新的映射,参数是一个pair类型的结构。这里需要用到另外一个 STL 模板——元组(pair)pair(1, 'a') 定义了一个整数1和字符a的pair。我们向映射中加入新映射对的时候就是通过加入pair来实现的。

如果插入的 key 之前已经有了 value,不会用插入的新的 value 替代原来的 value,也就是此次插入是无效的

#include 

#include 

using namespace std;

int main() {

   map dict;  // {}

   dict.insert(pair("Tom", 1)); // {"Tom"->1}

   dict.insert(pair("Jone", 2)); // {"Tom"->1, "Jone"->2}

   dict.insert(pair("Mary", 1)); // {"Tom"->1, "Jone"->2, "Mary"->1}

   dict.insert(pair("Tom", 2)); // {"Tom"->1, "Jone"->2, "Mary"->1}

   return 0;

}

在 Java 中通过put()向集合中添加元素,需要两个参数,第一个参数是 key,第二个参数是 value。

import java.util.HashMap;

public class HashMapTest {

   public static void main(String[] args) {

?     HashMap dict = new HashMap(); // {}

?     dict.put("Tom", 1); // {"Tom"->1}

?     dict.put("Jone", 2); // {"Tom"->1, "Jone"->2}

?     dict.put("Mary", 1); // {"Tom"->1, "Jone"->2, "Mary"->1}

?     dict.put("Tom", 2); // {"Tom"->2, "Jone"->2, "Mary"->1}

   }

}

访问映射

在 C++ 中访问映射和数组一样,直接用[]就能访问。比如dict["Tom"]就可以获取"Tom"的班级了。而这里有一个比较神奇的地方,如果没有对"Tom"做过映射的话,此时你访问dict["Tom"],系统将会自动为"Tom"生成一个映射,其value为对应类型的默认值。并且我们可以之后再给映射赋予新的值,比如dict["Tom"] = 3,这样为我们提供了另一种方便的插入手段。当然有些时候,我们不希望系统自动为我们生成映射,这时候我们需要检测"Tom"是否已经有映射了,如果已经有映射再继续访问。这时就需要用count()函数进行判断,在下一页中我们会详细介绍。

#include 

#include 

#include 

using namespace std;

int main() {

   map dict;  // {}

   dict["Tom"] = 1; // {"Tom"->1}

   dict["Jone"] = 2; // {"Tom"->1, "Jone"->2}

   dict["Mary"] = 1; // {"Tom"->1, "Jone"->2, "Mary"->1}

   printf("Mary is in class %d\n", dict["Mary"]);

   printf("Tom is in class %d\n", dict["Tom"]);

   return 0;

}

在 Java 中用get()方法获取 key 对应的 value。函数接受一个参数 key, 返回对应的 value, 如果 key 没有映射,返回null。

import java.util.HashMap;

public class HashMapTest {

   public static void main(String[] args) {

?     HashMap dict = new HashMap(); // {}

?     dict.put("Tom", 1); // {"Tom"->1}

?     dict.put("Jone", 2); // {"Tom"->1, "Jone"->2}

?     dict.put("Mary", 1); // {"Tom"->1, "Jone"->2, "Mary"->1}

?     System.out.println("Mary is in class " + dict.get("Mary"));

?     System.out.println("Tom is in class " + dict.get("Tom"));

   }

}

查找关键字

在 C++ 中,如果你想知道某个关键字是否被映射过,你可以直接用count()方法。如果被映射过,返回1,否则会返回0。

#include 

\#include 

\#include 

using namespace std;

int main() {

   map dict;  // {}

   dict["Tom"] = 1; // {"Tom"->1}

   dict["Jone"] = 2; // {"Tom"->1, "Jone"->2}

   dict["Mary"] = 1; // {"Tom"->1, "Jone"->2, "Mary"->1}

   if (dict.count("Mary")) {

?     printf("Mary is in class %d\n", dict["Mary"]);

   } else {

?     printf("Mary has no class");

   }

   return 0;

}

在 Java 中如果你想知道某个关键字是否被映射过,你可以直接用containsKey()方法。如果被映射过,返回true,否则会返回false。

import java.util.HashMap;

public class HashMapTest {

   public static void main(String[] args) {

?     HashMap dict = new HashMap(); // {}

?     dict.put("Tom", 1); // {"Tom"->1}

?     dict.put("Jone", 2); // {"Tom"->1, "Jone"->2}

?     dict.put("Mary", 1); // {"Tom"->1, "Jone"->2, "Mary"->1}

?     if (dict.containsKey("Mary")) {

?       System.out.println("Mary is in class " + dict.get("Mary"));

?     } else {

?       System.out.println("Mary has no class");

?     }

   }

}

遍历映射

在 C++ 中,通过迭代器可以访问映射中的每对映射,每个迭代器的first值对应 key,second值对应 value。

#include 

\#include 

\#include 

using namespace std;

int main() {

   map dict;  // {}

   dict["Tom"] = 1; // {"Tom"->1}

   dict["Jone"] = 2; // {"Tom"->1, "Jone"->2}

   dict["Mary"] = 1; // {"Tom"->1, "Jone"->2, "Mary"->1}

   for (map::iterator it = dict.begin(); it != dict.end(); ++it) {

 cout << it->first << " is in class " << it->second << endl;

   }

   return 0;

}

Java 中遍历映射的方法很多,在这里介绍一种效率最高的方法——利用Entry。

import java.util.HashMap;

public class HashMapTest {

   public static void main(String[] args) {

?     HashMap dict = new HashMap(); // {}

?     dict.put("Tom", 1); // {"Tom"->1}

?     dict.put("Jone", 2); // {"Tom"->1, "Jone"->2}

?     dict.put("Mary", 1); // {"Tom"->1, "Jone"->2, "Mary"->1}

?     for (HashMap.Entry entry : dict.entrySet()) {

?       System.out.println(entry.getKey() + " is in class " + entry.getValue());

?     }

   }

}

清空

C++ 和 Java 中都只需要调用clear()方法就可清空map或者HashMap。

C++ 中map常用方法总结:

*方法* *功能*
insert 插入一对映射
count 查找关键字
erase 删除关键字
size 获取映射对个数
clear 清空

Java 中HashMap常用方法总结:

*方法* *功能*
put 插入映射
get 获取关键字的值
containsKey 查找关键字
remove 删除关键字
size 获取映射对数
clear 清空

通过上面列举的方法,可以满足我们平时大多数的需求。关于map和HashMap更多方法,可以去参考文档,或者在网络上搜索资料查看。对于比赛来说,上面的方法已经足够了。

C++ map 官方参考文档

http://www.cplusplus.com/reference/map/map/erase/

Java HashMap 官方参考文档

http://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html