Java Map
Map是什么?
Map是Java中的一种数据集合类型,它是一种键值对的映射表(一个键key对应一个值value)。Map中的每个元素都包含一个键和一个值,键和值可以是任意类型的对象。Map中的键是唯一的,因此不能有重复的键。
Java中的map类似于Python里的dict。
Map的主要方法
1. put()
向Map中添加键值对。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
2. get() 根据键获取对应的值。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
//通过key “apple”获取它的值
int value = map.get("apple"); // 1
3. containsKey() 判断Map中是否包含指定的键。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
// map里是否包含"apple"和“orange”?
boolean containsApple = map.containsKey("apple"); // true
boolean containsOrange = map.containsKey("orange"); // false
4. containsValue() 判断Map中是否包含指定的值。
Map<String, Integer> map = new HashMap<>(); map.put("apple", 1); map.put("banana", 2);
// 是否包含值 1 和 3? boolean containsOne = map.containsValue(1); // true boolean containsThree = map.containsValue(3); // false
5. remove()
根据键删除对应的键值对。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.remove("apple");
6. size()
获取Map中键值对的数量。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
int size = map.size(); // 2
7. clear()
清空Map中的所有键值对。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.clear();
Map的实现类
Java中有多种Map的实现类,常用的有HashMap
、TreeMap
和LinkedHashMap
。最常用的是HashMap
。
1. HashMap
HashMap
是基于哈希表实现的Map
,它不保证键值对的顺序。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
2. TreeMap
TreeMap
可以对键进行排序。
Map<String, Integer> map = new TreeMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
3. LinkedHashMap LinkedHashMap是基于哈希表和链表实现的Map,它保证键值对的顺序与添加顺序一致。
Map<String, Integer> map = new LinkedHashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
Map的使用示例
import java.util.HashMap;
import java.util.Map;
public class MapExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
System.out.println("Map中的键值对数量:" + map.size()); // 3
int value = map.get("apple"); // 1
boolean containsApple = map.containsKey("apple"); // true
boolean containsGrape = map.containsKey("grape"); // false
System.out.println("Map中是否包含apple:" + containsApple); // true
System.out.println("Map中是否包含grape:" + containsGrape); // false
map.remove("banana");
System.out.println("Map中的键值对数量:" + map.size()); // 2
map.clear();
注意事项
通常我们遍历和操作Map,最好使用Iterator(同Set),Iterator会在处理过程中维护Map的结构不变。
例. 假设我们有一个HashMap,其中包含一些键值对:
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
map.put("grape", 4);
map.put("watermelon", 5);
现在,我们想要删除所有值小于等于3的键值对。我们可以使用Iterator来遍历这个HashMap并删除符合条件的键值对:
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
if (entry.getValue() <= 3) {
iterator.remove();
}
}
在这个例子中,
- 我们首先使用
entrySet()
方法获取HashMap
中所有的键值对,然后使用iterator()
方法获取一个Iterator
对象; - 接着,我们使用
hasNext()
方法检查是否还有下一个元素,如果有,我们使用next()
方法获取下一个元素,并使用getValue()
方法获取值; - 如果值小于等于3,我们使用
remove()
方法删除这个键值对。
完整案例
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class MapExample {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
map.put("grape", 4);
map.put("watermelon", 5);
System.out.println("before: " + map);
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
if (entry.getValue() <= 3) {
iterator.remove();
}
}
System.out.println("after: " + map);
}
}
运行结果
before: {banana=2, orange=3, apple=1, grape=4, watermelon=5}
after: {grape=4, watermelon=5}
一个完整的例子
- 如何使用常用的 Java Map 方法来实现一个简单的单词计数器。
例子:单词计数器
注意:需要先在project根目录创建一个example.txt
文件,并在里面写一些英文(以下方法只能通过空格和逗号句号等分割单词,所以只能统计英文词频)
可以从这里下载example.txt用来测试。
假设我们读取一个文本,我们希望计算文本里每个单词出现的次数。为了完成这个任务,我们可以使用 Java Map
来存储每个单词出现的次数。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MapFullExample {
public static void main(String[] args) {
// 读取project根目录下的example.txt文件,生成一个字符串text
String text = getStringFromFile("example.txt");
// 在不是alphanumeric characters的位置分割字符串,生成一个由单词组成的数组
String[] words = text.split("\\W+");
// 创建一个词频统计Map,Key是单词,Value是词频
Map<String, Integer> wordCountMap = new HashMap<>();
for (String word : words) {
String lowerCaseWord = word.toLowerCase(); // 先将每个单词转换成小写
Integer count = wordCountMap.get(lowerCaseWord); // 从现有Map中获取count数
if (count == null) { // 如果现有Map里不包含这个词,count就是null,此时把原有count设置为0
count = 0;
}
wordCountMap.put(word, count + 1); // 因为单词又出现了一次,所以count+1,然后保存回Map
}
// 打印单词和词频
for (Map.Entry<String, Integer> entry : wordCountMap.entrySet()) {
String word = entry.getKey().toLowerCase();
Integer count = entry.getValue();
System.out.println(word + ": " + count);
}
}
// 读取文档的方法,返回包含文档中所有行的一个String
private static String getStringFromFile(String fileName) {
// 创建StringBuilder对象sb, 用来将文件里读取的多行字符串组成一个字符串
StringBuilder sb = new StringBuilder();
// 一行一行读取文件,并添加到sb。如果文件不存在,抛出异常
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line; // 用来记录读到的每一行
while ((line = br.readLine()) != null) { //如果读取的一行不为空
sb.append(line); // 添加到sb
}
} catch (IOException e) {
e.printStackTrace();
}
String text = sb.toString(); // 生成一个String
return text;
}
}