Map 接口
Map 接口(双列集合的根接口)
1.以键值对形式保存数据
2.键和值一一映射,可以通过键来获取值
注意:
给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值。
当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常.
当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。
当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。
当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常。
map 的添加方法
HashMap<String,Integer> map = new HashMap<>();
Integer i1 = map.put("甲", 30);
Integer i2 = map.put("乙", 40);
Integer i3 = map.put("丙", 20);
System.out.println(map); // {甲=30, 乙=40, 丙=20}
Integer i4 = map.put("丙", 80);
// Integer 返回的是被覆盖的值,没被覆盖时,返回 null
System.out.println(i1); // null
System.out.println(i2); // null
System.out.println(i3); // null
System.out.println(i4); // 20
System.out.println(map); // {甲=30, 乙=40, 丙=80}
Map 基本方法
HashMap<String, Integer> map = new HashMap<>();
map.put("甲", 30);
map.put("乙", 20);
map.put("丙", 20);
// 是否包含 key
boolean containsKey = map.containsKey("甲");
System.out.println(containsKey); // true
// 是否包含 value
boolean containsValue = map.containsValue(20);
System.out.println(containsValue); // true
// 通过 key 获取对应 value
Integer integer1 = map.get("甲");
Integer integer2 = map.get("丁");
System.out.println(integer1); // 30
System.out.println(integer2); // null
// 获取所有 key 的 Set 集合
Set<String> keySet = map.keySet();
System.out.println(keySet); // [甲, 乙, 丙]
// 获取所有 value 的集合
Collection<Integer> values = map.values();
System.out.println(values); // [30, 20, 20]
// 通过 key 删除整个键值对
Integer remove = map.remove("乙");
Integer remove2 = map.remove("丁");
System.out.println(remove); // 20
System.out.println(remove2); // null
// 清空 map
map.clear();
System.out.println(map); // {}
Student 类:
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "[ 姓名 : " + name + " , 年龄 : " + age + " ]";
}
@Override
public int compareTo(Student o) {
int num = this.age - o.getAge();
return num == 0 ? 1 : num;
}
}
// 创建一个 map , key 保存学生, value 保存户籍
HashMap<Student, String> map = new HashMap<>();
map.put(new Student("鹏", 21), "安徽");
map.put(new Student("北", 22), "河南");
map.put(new Student("轩", 23), "江苏");
// 去重(重写 hashCode 和 equals 方法)
// 重写之后,key 相同, value 会被新值覆盖
map.put(new Student("北", 22), "河北");
System.out.println(map); // {[ 姓名 : 北 , 年龄 : 22 ]=河北, [ 姓名 : 轩 , 年龄 : 23 ]=江苏, [ 姓名 : 鹏 , 年龄 : 21 ]=安徽}
遍历 Map
迭代器遍历
HashMap<String, Integer> map = new HashMap<>();
map.put("甲", 30);
map.put("乙", 40);
map.put("丙", 20);
map.put("丁", 20);
// 通过 keySet 遍历
// 取出所有 key 的 Set 集合
Set<String> keySet = map.keySet();
// 获取迭代器
Iterator<String> iterator = keySet.iterator();
// 遍历所有 key
while (iterator.hasNext()) {
String key = iterator.next();
// 通过 key 获取对应 vlaue
Integer integer = map.get(key);
System.out.println("[ " + key + " : " + integer + " ]");
}
/*
* [ 丁 : 20 ]
* [ 甲 : 30 ]
* [ 乙 : 40 ]
* [ 丙 : 20 ]
*/
增强 for 循环遍历
HashMap<String, Integer> map = new HashMap<>();
map.put("甲", 30);
map.put("乙", 40);
map.put("丙", 20);
map.put("丁", 20);
Set<String> keySet = map.keySet();
for (String key : keySet) {
Integer integer = map.get(key);
System.out.println("[ " + key + " : " + integer + " ]");
}
/*
* [ 丁 : 20 ]
* [ 甲 : 30 ]
* [ 乙 : 40 ]
* [ 丙 : 20 ]
*/
通过获取键值对对象的 set 集合来遍历
HashMap<String, Integer> map = new HashMap<>();
map.put("甲", 30);
map.put("乙", 40);
map.put("丙", 20);
map.put("丁", 20);
// Entry 是 Map 中的内部接口,需要用 Map 来调用 Entry 所以是 Map. 系统自动生成时省略
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
// 获取迭代器
Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
// 获取 Entry 对象
Entry<String, Integer> entry = iterator.next();
// 获取 key
String key = entry.getKey();
// 获取 value
Integer value = entry.getValue();
System.out.println("[ " + key + " : " + value + " ]");// 或者 System.out.println(entry);
}
/*
* [ 丁 : 20 ]
* [ 甲 : 30 ]
* [ 乙 : 40 ]
* [ 丙 : 20 ]
*/
内部接口如:
interface InterA{
// InterB 是 InterA 的内部接口
interface InterB{
public abstract void fun();
}
}
// 创建一个类,实现 InterB 接口
//
class InterBImpl implements InterA.InterB{
@Override
public void fun() {
}
}
HashMap<String, Integer> map = new HashMap<>();
map.put("甲", 30);
map.put("乙", 20);
map.put("丙", 20);
map.put("丁", 20);
for (Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("[ " + key + " : " + value + " ]");
}
/*
* [ 丁 : 20 ]
* [ 甲 : 30 ]
* [ 乙 : 40 ]
* [ 丙 : 20 ]
*/
键盘输入字符串 统计字符串中每个字符出现的次数
System.out.println("请输入字符串");
Scanner scanner = new Scanner(System.in);
String string = scanner.nextLine();
// 转字符数组,为了取出每一个字符
char[] charArray = string.toCharArray();
// 创建 map
HashMap<Character, Integer> map = new HashMap<>();
// 遍历
for (int i = 0; i < charArray.length; i++) {
// 将每一个字符存入 map 中
// 判断要存的字符是否存在于 map 中
char key = charArray[i];
Integer value = map.get(key);
if (value == null) {
// key 不存在 map 中
map.put(key, 1);
} else {
// key 存在于 map 中
// 利用 key 把对应值取出来 + 1
Integer v = map.put(charArray[i], 1);
// 重新存回去,覆盖原先 value 的部分
map.put(key, v + 1);
}
}
System.out.println(map);
scanner.close();
// 请输入字符串
// asddwqdsadqwdsdgvfgdhjsfgjdfggdsgf
// {a=2, q=2, s=5, d=9, v=1, f=4, w=2, g=6, h=1, j=2}
LindedHashMap
LinkedHashMap
特点:有序(怎么存储,怎么打印)
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("鹏", 18);
map.put("忠", 22);
map.put("水", 20);
map.put("茜", 28);
System.out.println(map); // {鹏=18, 忠=22, 水=20, 茜=28}
// 创建一个 treemap key 保存学生, value 保存户籍
// 按年龄排序
TreeMap<Student, String> map = new TreeMap<>();
map.put(new Student("鹏", 21), "安徽");
map.put(new Student("北", 22), "河南");
map.put(new Student("轩", 23), "江苏");
map.put(new Student("水", 18), "浙江");
for (Entry<Student, String> entry : map.entrySet()) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println("[ " + key + " 来自 : " + value + " ]");
}
/*
* [ [ 姓名 : 水 , 年龄 : 18 ] 来自 : 浙江 ]
* [ [ 姓名 : 鹏 , 年龄 : 21 ] 来自 : 安徽 ]
* [ [ 姓名 : 北 , 年龄 : 22 ] 来自 : 河南 ]
* [ [ 姓名 : 轩 , 年龄 : 23 ] 来自 : 江苏 ]
*/
// Collection 类中的方法(静态方法)
ArrayList<Integer> list = new ArrayList<>();
list.add(12);// 自动装箱
list.add(10);
list.add(84);
list.add(20);
list.add(24);
list.add(36);
list.add(42);
list.add(57);
System.out.println(list); // [12, 10, 84, 20, 24, 36, 42, 57]
// 随机交换集合中值得位置(洗牌)
Collections.shuffle(list);
System.out.println(list); // [12, 42, 24, 84, 20, 10, 36, 57]
// 排序
Collections.sort(list);
System.out.println(list); // [10, 12, 20, 24, 36, 42, 57, 84]
// 二分查找
int index = Collections.binarySearch(list, 36);
System.out.println(index); // 4
// 反转集合
Collections.reverse(list);
System.out.println(list); // [84, 57, 42, 36, 24, 20, 12, 10]
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("北", 22));
list.add(new Student("鹏", 21));
list.add(new Student("轩", 23));
// 排序(对象排序时,需要实现 Comparable 接口,编写排序规则)
Collections.sort(list);
System.out.println(list); // [[ 姓名 : 鹏 , 年龄 : 21 ], [ 姓名 : 北 , 年龄 : 22 ], [ 姓名 : 轩 , 年龄 : 23 ]]
/*
* 使用 ArrayList 模拟三人斗地主
* 1.洗牌
* 2.发牌
* 3.看牌
* 分析:
* 1.先创建一副牌(使用 ArrayList)
* 2.洗牌(suffle)
* 3.发牌分三人(三个 list)和底牌部分(list)
* 4.看牌(打印 list)
*
*/
public class Demo {
public static void main(String[] args) {
ArrayList<String> poker = new ArrayList<>();
// 拼接字符串
String[] AllColors = {"黑桃","红桃","梅花","方片"};
String[] AllNum = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
for (String colors : AllColors) {
for (String num : AllNum) {
// 拼接字符串
String pokerStr = colors + num;
// 把牌装进集合中
poker.add(pokerStr);
}
}
// 添加大小王
poker.add("小王");
poker.add("大王");
// 洗牌
Collections.shuffle(poker);
// 创建4个装牌的集合
// 0 3 6 9
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<String> list3 = new ArrayList<>();
ArrayList<String> list4 = new ArrayList<>();
// 遍历牌的集合
for (int i = 0; i < poker.size(); i++) {
// 把每一张牌取出来
String pokers = poker.get(i);
// 按发牌顺序添加不同集合中
if (i > 50) {
// 51 52 53
list4.add(pokers);
} else if (i % 3 == 0) {
// 给第一个人发牌
list1.add(pokers);
} else if (i % 3 == 1) {
// 给第二个人发牌
list2.add(pokers);
}else{
// 给第三个人发牌
list3.add(pokers);
}
}
System.out.println("鹏的手牌:");
System.out.println(list1);
System.out.println("水的手牌:");
System.out.println(list2);
System.out.println("孟的手牌:");
System.out.println(list3);
System.out.println("底牌:");
System.out.println(list4);
}
}
/*
* 鹏的手牌:
* [方片9, 黑桃Q, 梅花9, 方片3, 黑桃J, 黑桃9, 方片4, 红桃A, 黑桃A, 梅花7, 方片K, 方片10, 梅花8, 黑桃6, 黑桃3, 黑桃7, 黑桃5]
* 水的手牌:
* [红桃J, 方片7, 梅花10, 方片2, 红桃10, 梅花A, 大王, 梅花2, 方片Q, 红桃8, 红桃9, 红桃5, 黑桃4, 方片8, 梅花6, 方片A, 红桃3]
* 孟的手牌:
* [梅花J, 红桃7, 小王, 黑桃K, 红桃K, 梅花5, 黑桃10, 红桃4, 梅花K, 红桃2, 方片J, 梅花4, 红桃6, 红桃Q, 梅花Q, 方片5, 方片6]
* 底牌:
* [黑桃8, 梅花3, 黑桃2]
*/
/*
* 使用 map 模拟三人斗地主
* 1.洗牌
* 2.发牌
* 3.看牌
*/
public class Demo {
public static void main(String[] args) {
// 创建 map 集合
HashMap<Integer, String> poker = new HashMap<>();
// 创建一个集合,保存索引
ArrayList<Integer> list = new ArrayList<>();
// 创建牌的索引
int index = 1;
// 拼接字符串
String[] AllColors = {"黑桃","红桃","梅花","方片"};
String[] AllNum = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
for (String num: AllNum) {
for (String colors : AllColors) {
// 拼接字符串
String string = colors + num;
// 把牌装进集合中
poker.put(index, string);
// 把索引装进 list 中(为洗牌准备)
list.add(index);
// 让索引自增
index++;
}
}
// map 中添加大小王,list 中添加 index,index 自增
poker.put(index, "小王");
list.add(index++);
poker.put(index, "大王");
list.add(index);
// 洗牌(随机排序索引)
Collections.shuffle(list);
// 发牌(将索引发出去)
// 创建4个 TreeSet 保存索引
TreeSet<Integer> set1 = new TreeSet<>();
TreeSet<Integer> set2 = new TreeSet<>();
TreeSet<Integer> set3 = new TreeSet<>();
TreeSet<Integer> set4 = new TreeSet<>();
// 发牌(发索引)
for (int i = 0; i < list.size(); i++) {
// 取出每个索引
Integer integer = list.get(i);
// 按顺序发牌
if (i > 50) {
set4.add(integer);
} else if (i % 3 == 0) {
// 给第一个人发牌
set1.add(integer);
} else if (i % 3 == 1) {
// 给第二个人发牌
set2.add(integer);
}else{
// 给第三个人发牌
set3.add(integer);
}
}
// 看牌(去 map 中使用索引把对应的牌取出来打印)
lookPokers(poker, set1, "鹏");
lookPokers(poker, set2, "水");
lookPokers(poker, set3, "龙");
lookPokers(poker, set4, "底牌");
}
// 看牌的方法
public static void lookPokers(HashMap<Integer, String> map, TreeSet<Integer> set, String name) {
if (!name.equals("底牌")) {
System.out.println(name + "的手牌:");
} else {
System.out.println("底牌:");
}
// 遍历索引的 set, 取出每一个索引,再去 map 中找到对应的牌
for (Integer key : set) {
// 取出的牌
String string = map.get(key);
System.out.print(string + " ");
}
System.out.println();
}
}
/*
* 鹏的手牌:
* 梅花3 黑桃4 方片4 梅花5 方片5 方片6 红桃7 梅花7 黑桃10 梅花10 红桃J 方片Q 梅花K 方片K 红桃2 方片2 小王
* 水的手牌:
* 方片3 红桃4 梅花4 黑桃5 黑桃6 梅花6 黑桃7 红桃8 梅花8 方片9 红桃10 梅花J 方片J 红桃Q 黑桃K 黑桃A 红桃A
* 龙的手牌:
* 红桃3 红桃5 红桃6 方片8 黑桃9 红桃9 梅花9 方片10 黑桃J 黑桃Q 梅花Q 红桃K 梅花A 方片A 黑桃2 梅花2 大王
* 底牌:
* 黑桃3 方片7 黑桃8
*/
Map 的嵌套
/*
* Java学科
* java 1班 -- 保存是学生 和 户籍
* java 2班 -- 保存是学生 和 户籍
*
* Java学科 是一个map
* 保存了两个键值对 ---- 1班 和 2班
*
* 1班 也是一个 map
* 保存 ---- 学生 户籍
*/
public class Demo {
public static void main(String[] args) {
HashMap<Student, String> class1 = new HashMap<>();// 1班
HashMap<Student, String> class2 = new HashMap<>();// 2班
HashMap<HashMap<Student, String>, String> subject = new HashMap<>();// 学科
class1.put(new Student("鹏", 21), "安徽");
class1.put(new Student("北", 22), "河南");
class1.put(new Student("剑", 20), "江苏");
class2.put(new Student("轩", 23), "江苏");
class2.put(new Student("水", 19), "浙江");
class2.put(new Student("孟", 18), "浙江");
subject.put(class1, "Java1班");
subject.put(class2, "Java2班");
// 遍历学科,找到班
for (HashMap<Student, String> classes : subject.keySet()) {
// 先获取学科的 value
String subjectValue = subject.get(classes);
System.out.println(subjectValue + ":");
// 遍历班,打印学生和对应户籍
for (Student student : classes.keySet()) {
// 打印班对应的 value(学生的户籍)
String classesValue = classes.get(student);
System.out.println(student + " 户籍 : " + classesValue);
}
System.out.println();
}
}
}
/*
* Java1班:
* [ 姓名 : 北 , 年龄 : 22 ] 户籍 : 河南
* [ 姓名 : 鹏 , 年龄 : 21 ] 户籍 : 安徽
* [ 姓名 : 剑 , 年龄 : 20 ] 户籍 : 江苏
*
* Java2班:
* [ 姓名 : 水 , 年龄 : 19 ] 户籍 : 浙江
* [ 姓名 : 轩 , 年龄 : 23 ] 户籍 : 江苏
* [ 姓名 : 孟 , 年龄 : 18 ] 户籍 : 浙江
*/