Map集合
Map集合图解
Map集合常用子类
Map(接口):所有双列集合的“父接口”,它内部定义了所有“双列集合”所应该具有的所有方法。
- HashMap(子类):“键”是“哈希表结构”——无序、不重复。
- LinkedHashMap(子类):“键”是“链表 + 哈希表结构”——有序、不重复
- TreeMap(子类):“键”是“红黑树”——排序、不重复
注意:Map的子类的“数据结构”都是应用在“键”上。
“键”不能重复,但“值”可以重复。
Map集合常用方法:
-
增,改:
public V put(K key, V value):向集合中添加一个键值对。关于返回值: 1,正常添加键值对:返回null System.out.println(map.put("金蟾童子","唐三藏"));//null 2,如果添加的键值对的键(key)在集合中已经存在了,就会用新值替换掉原值,并返回原值。 System.out.println(map.put("金蟾童子","牛魔王"));//唐三藏(会用牛魔王替换掉唐三藏,返回值是:唐三藏)。
-
删:
- public void clear();//清空集合中所有元素。
- public V remove (Object key);//把指定的键所对应的键值对元素在Map集合中删除,并返回删除元素的值。
-
改(put)
-
查:
- public V get(Object key):根据指定的键,在Map集合中获取对应的值。
- public Set keySet();//获取Map集合中的所有值,存储到Set集合中。《遍历》
- public Set<Map.Entry<K,V>> entrySet();//获取Map集合中所有键值对对象的集合(Set集合)。《遍历》
- public boolean containsKey(Object key);//判断该集合中是否存在键。
- public boolean containsValue(Object value);//判断该集合中是否存在“值”。
Map集合遍历的两种方式
Map集合不能直接遍历,只能间接的获取Set集合,然后遍历Set集合,达到遍历Map的效果。
第一种方式:键找值
方法:public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。【遍历-掌握】
代码演示:
public class Demo02 {
public static void main(String[] args) {
//1.定义一个Map
Map<String, String> map = new HashMap<>();
//2.存储一些数据:
map.put("齐天大圣", "孙悟空");
map.put("天蓬元帅", "猪八戒");
map.put("卷帘大将", "沙和尚");
map.put("金蝉童子", "唐三藏");
//3.遍历
Set<String> keys = map.keySet();//获取所有"键"的Set集合
for (String k : keys) {//遍历Set集合,取出每个"键"
System.out.println(k + " = " + map.get(k));//调用map.get(键)获取对应的"值"
}
}
}
第二种方式:键值对
方法:public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。【遍历】
代码演示:
public class Demo03 {
public static void main(String[] args) {
//1.定义一个Map
Map<String, String> map = new HashMap<>();
//2.存储一些数据:
map.put("齐天大圣", "孙悟空");//Entry子类对象("齐天大圣","孙悟空")
map.put("天蓬元帅", "猪八戒");//Entry子类对象("天蓬元帅", "猪八戒")
map.put("卷帘大将", "沙和尚");//Entry子类对象("卷帘大将", "沙和尚")
map.put("金蝉童子", "唐三藏");//Entry子类对象("金蝉童子", "唐三藏")
//3.遍历
Set<Map.Entry<String,String>> es = map.entrySet();//Entry是一个Map接口中的"内部接口",所以:Map.Entry
for (Map.Entry<String, String> e : es) {
String key = e.getKey();
String value = e.getValue();
System.out.println(key + " = " + value);
}
}
}
两种方式遍历的示意图:
两种方式的区别
- 第一种方式:要先将Map中所有“键”封装到一个Set中;然后再遍历所有“键的集合”,然后再通过“每个键”,再去Map中找“值”;
写法简单【常用】 - 第二种方式:先将Map中的所有的Entry对象封装到一个Set中,然后再遍历所有的”Entry集合”,然后再获取每个Entry中的“键”和“值”;
步骤少,效率高一些。
更加“面向对象”;
HashMap使用自定义对象做键
1.之前我们使用String做键,String做值使用了HashMap。对于Map集合的“键和值”可以是“任何对象”,我们使用“自定义对象”做键试一下。
2.注意:使用“自定义对象”做“键”,自定义对象要重写hashCode()和equals()方法
1).Student类:
public 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 void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + 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);
}
}
2).测试类:
public class Demo04 {
public static void main(String[] args) {
//1.定义一个Map集合
Map<Student, String> map = new HashMap<>();
//2.存储对象
map.put(new Student("张三", 18), "it001");
map.put(new Student("李四", 18), "it002");
map.put(new Student("李四", 18), "it003");//要求Student要重写hashCode()和equals(),就可以验证出重复了。
//3.遍历
Set<Student> keys = map.keySet();
for (Student stu : keys) {
System.out.println(stu + " = " + map.get(stu));
}
}
}
LinkedHashMap的基本使用
- LinkedHashMap:键“链表 + 哈希表”结构,有序的:
链表:保证顺序;
哈希表:保证唯一。
代码演示:
public class Demo05 {
public static void main(String[] args) {
//1.定义一个集合
// HashMap<String, String> map = new HashMap<>();//无序的;
LinkedHashMap<String, String> map = new LinkedHashMap<>();//有序的;
//2.存储一些对象
map.put("it001", "黄渤");
map.put("it002", "黄磊");
map.put("it003", "郭德纲");
map.put("it004", "于谦");
//4.遍历
Set<Map.Entry<String, String>> es = map.entrySet();
for (Map.Entry<String, String> e : es) {
String key = e.getKey();
String value = e.getValue();
System.out.println(key + " = " + value);//跟存入的顺序一致
}
}
}
TreeMap集合的基本使用:
- TreeMap:对元素进行“比较”(使用被排序元素的compareTo方法)并排序;
代码演示:
1).Student类:需要实现Comparable接口,并重写compareTo()方法
public 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 void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
//先按年龄比,如果年龄相同,按姓名比
int n = this.age - o.age;
if (n == 0) {//年龄相同,然后再按"姓名"比
n = this.name.compareTo(o.name);
}
return n;
}
}
2).测试类:
public class Demo06 {
public static void main(String[] args) {
String s1 = "你好";//20320(Unicode编码)
String s2 = "我好";//25105(Unicode编码)
System.out.println(s1.compareTo(s2));//-4785
//1.创建一个TreeMap集合
TreeMap<String, String> map = new TreeMap<>();
//2.存储一些元素
map.put("cba", "张三");
map.put("bac", "李四");
map.put("acb", "王五");
map.put("cab", "周六");
//3.遍历
Set<String> keys = map.keySet();
for (String k : keys) {
System.out.println(k + " = " + map.get(k));
}
//定义一个集合
TreeMap<Student, String> tm = new TreeMap<>();
tm.put(new Student("张三", 18), "it001");
tm.put(new Student("李四", 18), "it002");
tm.put(new Student("王五", 18), "it003");
tm.put(new Student("王五", 18), "it004");
Set<Student> stuKeys = tm.keySet();
for (Student stuKey : stuKeys) {
System.out.println(stuKey + " = " + tm.get(stuKey));
}
}
}
Map集合练习_计算每个字符出现的次数
代码图示:
代码演示:
public class Demo07 {
public static void main(String[] args) {
String str = "fjejfieslfji1jkfeowkdslefd";
//统计str中每个字符出现的次数。
Map<Character, Integer> map = new HashMap<>();
//遍历字符串
for(int i = 0; i < str.length() ; i++) {
//取出每个字符
char c = str.charAt(i);
//判断map中是否有这个"键"
if (map.containsKey(c)) {//有
map.put(c , map.get(c) + 1);
}else{
map.put(c, 1);
}
}
//打印Map
Set<Character> keys = map.keySet();
for (Character k : keys) {
System.out.println("字符 " + k + " 共出现:" + map.get(k) + " 次");
}
}
}