文章目录
1.Map集合概述
Map集合是一种双列集合,每个元素包含两个值,也被称为”键值对集合“。
元素格式:key=value(键值对元素)
Map:存储时必须保持键的唯一性。
ps: Collection一次添加一个元素,称为”单列集合“。
2.Map集合特点
- Map集合的特点都是由键决定
- 键值无序,不重复,无索引的。后面重复的键会覆盖前面的整个元素。
- 值无要求
- 键值对都可以为null
3.Map常用子类
-
HashTable:内部结构是哈希表,同步。不允许null作为键,不允许null作为值。
—Properties:用来存储键值对型的配置文件的信息,可以和IO技术结合。 -
HashMap:内部结构是哈希表,不同步。允许null作为键,允许null作为值。
-
TreeMap:内部结构是二叉树,不同步。对Map集合中的键进行排序
4.Map集合常用方法
4.1 添加
value put(key,value):返回前一个和key关联的值,如果没有,返回null
4.2 删除
void clear():清空Map集合
value remove(key):根据指定的key删除这个键值对
4.3 判断
boolean containsKey(key):是否包含值
boolean containsValue(value):是否包含键
boolean isEmpty()
4.4 获取
value get(key):通过键获取值,如果没有键则返回null。可以通过是否返回null判断该键是否存在。
int size():获取键值对的个数
Map<String,Integer> map = new HashMap<String,Integer>();
System.out.println(map.put("abc1",21));//null
System.out.println(map.put("abc2",22));//null
System.out.println(map.put("abc2",23));//22
System.out.println(map.size());//2
System.out.println(map.containsKey("abc2"));//true
System.out.println(map.containsKey("abc3"));//false
System.out.println(map.containsValue(21));//true
System.out.println(map.containsValue(22));//false
System.out.println(map.get("abc2"));//23
System.out.println(map.get("abc3"));//null
System.out.println(map.remove("abc1"));//21
System.out.println(map.remove("abc3"));//null
map.clear();
System.out.println(map);// { }
5.Map集合的3种遍历方式
5.1 keySet()
调用keySet()方法,获取Map集合所有的键,再找值
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc1", 21);
map.put("abc2", 22);
map.put("abc3", 23);
//keySet
Set<String> set = map.keySet();//键不可以重复,用set集合装
for (String s : set) {
System.out.println(map.get(s));//通过键找值
}
5.2 values()
调用value()方法,将值放到Collection集合中,再遍历
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc1", 21);
map.put("abc2", 22);
map.put("abc3", 23);
//values
Collection<Integer> collection = map.values();//值可以重复,用Collection集合装
for (Integer i : collection) {
System.out.println(i);
}
5.3 entrySet()
-
用entrySet()方法,把Map集合转成Set集合,集合里的对象类型为:Map.entry<K,V>
-
用foreach调出Set集合中的每个对象,运用getKey()和getValue()调出对象的键和值
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc1", 21);
map.put("abc2", 22);
map.put("abc3", 23);
//entrySet
Set<Map.Entry<String,Integer>> setMe = map.entrySet();
for (Map.Entry<String,Integer> me : setMe) {
System.out.println(me.getKey()+":"+me.getValue());
}
5.4 Lambda表达式
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc1", 21);
map.put("abc2", 22);
map.put("abc3", 23);
//Lambda表达式
map.forEach((k,v)->{
System.out.println(k+":"+v);
});
6.Map集合存储自定义对象
6.1 HashMap存储自定义对象
当map中的键相同时,会把之前的那对元素去掉。
在下列代码中,往HashMap集合中加入一对键为学生类的对象。现在要求当学生对象中的姓名和年龄相同时为同一个学生,因为计算机默认Map集合中元素地址不同,键不同,,也就是说,即使现在学生的姓名和年龄都一样,但是创建时实例的地址不同,那么就被认定不同。为完成上述需求,应重写Student类中的hashCode()和equals()方法。
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Demo {
public static void main(String[] args) {
HashMap<Student,String> map = new HashMap<>();
map.put(new Student("张三",21),"北京");
map.put(new Student("李四",23),"上海");
map.put(new Student("王五",25),"广东");
map.put(new Student("李四",23),"新疆");
map.forEach((stu,str)->{
System.out.println(stu.getName()+":"+stu.getAge()+"——"+str);
});
}
}
6.2 TreeMap存储自定义对象
键对象所属的类需要实现Comparable接口或者TreeMap拥有比较器,之后才能存储自定义对象
import java.util.*;
class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Student o) {
int temp = this.getName().compareTo(o.getName());
return temp==0 ? this.getAge()-o.getAge() : temp;
}
}
public class Demo {
public static void main(String[] args) {
TreeMap<Student,String> map = new TreeMap<>(/*new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int temp = o2.getName().compareTo(o1.getName());
return temp==0 ? o2.getAge()-o1.getAge() : temp;
}
}*/);
map.put(new Student("zhangsan",21),"北京");
map.put(new Student("lisi",23),"上海");
map.put(new Student("wangwu",25),"广东");
map.put(new Student("lisi",23),"新疆");
map.forEach((stu,str)->{
System.out.println(stu.getName()+":"+stu.getAge()+"——"+str);
});
}
}
7.代码示例
要求:统计字符串中每个字符出现的次数
//录入字符串
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
//将字符串转成字符数组
char[] cc = s.toCharArray();
//创建Map集合
Map<Character,Integer> map = new TreeMap<Character,Integer>();
//依次判断Map集合中是否有该字符
for(char c : cc) {
Integer i = map.get(c);
if (i==null) {
map.put(c,1);
}else {
i++;
map.put(c,i);
}
}
//创建字符串缓冲区
StringBuilder sb = new StringBuilder();
//遍历Map集合并将键值录入字符串缓冲区
Set<Map.Entry<Character, Integer>> entries = map.entrySet();
for (Map.Entry<Character, Integer>me : entries) {
sb.append(me.getKey()).append("(").append(me.getValue()).append(")");
}
//输出内容
System.out.println(sb.toString());
}