Map
概述
1、Map:翻译是“地图”
地图:纸上的点和现实生活中的某个实际位置的对应关系
2、java中的Map:
用于记录一个数据到另外一个数据的对应关系
3、对应关系:
计算式、表达式
f(x) = x*x + 1,其中x属于正整数中的[-1, 3]
罗列穷举的方式:
{-1=2, 0=1, 1=2, 2=5, 3=10}
4、java中使用的第二种表达对应关系的方式,地图也是通过穷举的方式来表达对应关系,字典(通过穷举的方式,表达字到解释的对应关系)
5、Map的特点:
1、对应关系,区分为“键”和“值”,其中:
键,称为key,记录一些简单的,容易记忆的信息
值,称为value,记录一些复杂的,最终要获取的,不容易记忆的信息
2、键是唯一的,否则同样的键就会对应不同的值,这样就丧失了对应关系的作用,产生了二义性
3、一个键只能对应一个值
4、值可以重复,多个键可以对应到同一个值
Map中的简单方法
1、说明:
Map是一个接口,用于定义双列集合中,应该具有哪些功能
2、常用功能:
put(K key, V value)
如果key没有存在于集合中,那么就是添加一对键值对
remove(Object key)
根据指定的键删除键值对
put(K key, V value)
如果key已经存在于集合中,那么就是修改对应的值
get(Object obj)
根据给定的键,获取对应的值
size()
获取键值对对数
clear()
清空集合
containsKey(Object obj)
判断集合中是否存在obj键
containsValue(Object obj)
判断集合中是否有某个值
isEmpty()
判断集合是否为空
代码示例
import java.util.HashMap;
import java.util.Map;
public class Demo04_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("abc", 3);
map.put("qq", 2);
map.put("zxcv", 4);
map.put("", 666);
System.out.println(map);
System.out.println(map.get("abc"));
map.remove("abc");
System.out.println(map);
map.put("", 0);
System.out.println(map);
System.out.println(map.isEmpty());
System.out.println(map.size());
System.out.println(map.containsKey(""));
System.out.println(map.containsValue(666));
map.clear();
System.out.println(map);
}
}
Map的遍历
1、概述:
1、不能直接遍历,只能获取Map中的某些信息之后,或者对Map做一些转换之后,间接的遍历
2、对于Map的转换有两种思路:获取Map中的所有的键,根据键获取对应的值;获取Map中的所有键值对对象,分别获取每个键值对对象中的键和值
2、两种思路,每种思路对应两种遍历方式
1、原因:获取了所有键形成一个Set集合,获取了所有的键值对对象也会形成一个Set集合
2、两种方式:遍历Set集合的时候,可以使用迭代器或者增强for两种方式
Map的第一种遍历思路:根据键获取值
1、步骤:
1、获取所有键的Set集合
2、使用Set的遍历方式,遍历Set集合,拿到每个键(迭代器、增强for)
3、根据当前键获取对应的值
2、涉及到的方法:
1、Set<K> keySet()
2、V get(K key)
Map的第二种遍历思路:根据键值对对象获取键和值
1、步骤:
1、获取所有键值对对象的Set集合
2、遍历键值对对象的Set集合,获取每一个键值对对象(迭代器、增强for)
3、根据键值对对象的方法,获取键值对对象中的键和值
2、涉及到的类和方法
一、键值对对象:实现了Map.Entry接口的实现类对象
1、entry:条目
2、Map.Entry记录的是键值对中的键和值的一个对象
3、Map是一个接口,Map.Entry是Map接口中的一个内部接口
4、有两个方法:getKey获取键、getValue()获取值
二、获取了键值对对象之后,就不需要再依赖原来的Map集合了
代码示例
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Demo05_Map的遍历 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("abc", 3);
map.put("qq", 2);
map.put("zxcv", 4);
map.put("", 666);
test22_根据键值对对象获取键和值_增强for(map);
}
private static void test22_根据键值对对象获取键和值_增强for(Map<String, Integer> map) {
for (Map.Entry<String, Integer> en : map.entrySet()) {
System.out.println(en.getKey() + "..." + en.getValue());
}
}
private static void test21_根据键值对对象获取键和值_迭代器(Map<String, Integer> map) {
//获取所有的键值对对象的Set集合
Set<Map.Entry<String, Integer>> entrys = map.entrySet();
//迭代器
Iterator<Map.Entry<String, Integer>> it = entrys.iterator();
while (it.hasNext()) {
//获取下一个键值对对象
Map.Entry<String, Integer> en = it.next();
//获取该键值对对象的键
String key = en.getKey();
//获取该键值对对象的值
int value = en.getValue();
System.out.println(key + "..." + value);
}
}
private static void test12_根据键获取值_增强for(Map<String, Integer> map) {
//根据键获取值
for (String key : map.keySet()) {
System.out.println(key + "..." + map.get(key));
}
}
private static void test11_根据键获取值_迭代器(Map<String, Integer> map) {
//获取所有键的Set集合
Set<String> keys = map.keySet();
//遍历Set集合
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
int value = map.get(key);
System.out.println(key + "..." + value);
}
}
}
练习:键盘录入一个字符串,统计每个字符出现的次数
代码示例
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Demo06_统计练习 {
public static void main(String[] args) {
// 键盘录入一个字符串,统计每个字符出现的次数
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
char[] chs = line.toCharArray();
//准备一个可以用于统计的容器,字符和次数的对应关系
Map<Character, Integer> map = new HashMap<>();
for (char c : chs) {
/*if (map.containsKey(c)) {
int count = map.get(c);
map.put(c, count + 1);
} else {
map.put(c, 1);
}*/
map.put(c, map.containsKey(c) ? map.get(c) + 1 : 1);
}
System.out.println(map);
//要求打印结果为:a有4个,b有4个,。。。。, ^有2个。
System.out.println(getString(map));
}
public static String getString(Map<Character, Integer> map) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<Character, Integer> en : map.entrySet()) {
char c = en.getKey();
int v = en.getValue();
sb.append(c).append("有").append(v).append("个,");
}
sb.replace(sb.length() - 1, sb.length(), "。");
return sb.toString();
}
}
HashMap
概述
1、就是Map的一个实现类,通过哈希存储的方式实现
2、查看HashSet的源代码:
1、HashSet其实底层就是HashMap,HashSet是HashMap实现的
2、HashSet的元素的所有特性,都可以移植到HashMap的键上
3、HashSet保证元素唯一性的原理,和HashMap保证键的唯一性原理相同
4、HashSet中的元素类型需要重写hashCode和equals方法,HashMap中的键的类型也需要重写
3、源码截图:
LinkedHashMap
1、可以保证键的存储顺序和取出顺序一致
2、是HashMap的子类,是Map的实现类
代码示例
import java.util.LinkedHashMap;
public class Demo08_LinkedHashMap {
public static void main(String[] args) {
LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();
lhm.put("asdf", 4);
lhm.put("qq", 2);
lhm.put("xyz", 3);
System.out.println(lhm);
}
}
HashMap和Hashtable的比较
1、相同点:
1、都是Map的实现类
2、都是哈希存储的方式
3、两者成员方法几乎完全一样
2、不同点:
1、版本不同:HashMap在jdk1.2,Hashtable在jdk1.0
2、线程安全性不同:
HashMap线程不安全的,效率高
Hashtable线程安全的,效率低
3、有关null的存储不同
HashMap可以存储null键null值
Hashtable不能存储null键null值
4、命名规范不同:
Hashtable第二个单词的首字母没有大写
代码示例
import java.util.HashMap;
import java.util.Hashtable;
public class Demo09_HashMap和Hashtable的比较 {
public static void main(String[] args) {
HashMap<String, String> hm = new HashMap<>();
hm.put(null, "");
hm.put("kong", null);
hm.put(null, null);
System.out.println(hm);
}
private static void test1_Hashtable不能存储null键null值() {
Hashtable<String, String> ht = new Hashtable<>();
// ht.put(null, "");
// ht.put("", null);
// ht.put(null, null);
System.out.println(ht);
}
}
到此为止我们的集合就告一段落了,接下来我也会陆续更新java方面的知识总结。