Java中的Map

1.Map概述

Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
创建Map集合的对象:因为Map是接口,不能直接创建对象,所以我们使用多态的方式来创建.在这里我们可以创建实现类HashMap的对象

2.Map集合的功能

方法名 说明
V put(Object key, V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 清空Map中所有元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 获取集合长度,即集合中键个数
V get(Object key) 根据键获取值
Set KeySet() 获取所有键的集合
Collection values() 获取所有值的集合
Set> entrySet() 获取所有键值对象的集合
V getOrDefault(Object key, V defaultValue) 当Map集合中有这个key时,就使用这个key对应的value值,如果没有就使用默认值defaultValue

代码演示:

1.Map集合的基本功能

package com.zzu.map;

import java.util.HashMap;
import java.util.Map;

public class Demo1 {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();//创建HashMap对象
        map.put("name","jh");//key value
        map.put("age","nineteen");
        map.put("sex","male");

        System.out.println(map.remove("age"));//nineteen
        System.out.println(map);
        System.out.println(map.containsKey("name"));//true
        System.out.println(map.containsValue("nineteen"));//false age已经remove
        System.out.println(map.isEmpty());//false
        System.out.println(map.size());//2
        map.clear();//清空
        System.out.println(map.isEmpty());//true
        System.out.println(map.size());//0

    }
}

输出结果:

nineteen
{sex=male, name=jh}
true
false
false
2
true
0

2.Map集合的获取功能

package com.zzu.map;

import java.util.*;

public class Demo2 {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();
        map.put("name","jh");
        map.put("age","nineteen");
        map.put("sex","male");

        System.out.println(map.get("sex"));//获取male
        System.out.println("----------");

        System.out.println(map.keySet());//获取键集合
        Set<String> ketSet=map.keySet();
        for(String s:ketSet){
            System.out.println(s);
        }
        System.out.println("----------");

        System.out.println(map.values());//获取值集合
        Collection<String> collection=map.values();
        for(String s:collection){
            System.out.println(s);
        }
        System.out.println("----------");

        System.out.println(map.entrySet());//获取所有键值对象集合
        Set<Map.Entry<String,String>> setMapEntry = map.entrySet();
        System.out.println(setMapEntry);
    }
}

输出结果:

male
----------
[sex, name, age]
sex
name
age
----------
[male, jh, nineteen]
male
jh
nineteen
----------
[sex=male, name=jh, age=nineteen]
[sex=male, name=jh, age=nineteen]

3.Map的getOrDefault()方法

package com.zzu.map;

import java.util.HashMap;
import java.util.Map;

public class Demo3 {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();
        map.put("name","jh");
        map.put("age","nineteen");
        map.put("sex","male");

        System.out.println(map.getOrDefault("name", "111"));//jh
        System.out.println(map.getOrDefault("time", "666"));//666
    }
}

3.巩固拓展

1.HashMap存储自定义对象实现键值唯一

重点:放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写hashCode和equals方法
IDEA在源码中已经在HashMap中重写了上述两种方法

import java.util.Objects;

/*
类Student 重写其equals(),toString()方法 满足:
    (1).比学号、姓名、性别
    (2).System.out.println(new Student())输出信息:"学号:,姓名:(性别)"
    (3).数组存放,实现头插、学号序输出、不重复的输入输出
 */
public class Student {
    private String id;
    private String name;
    private String sex;

    public Student() {
    }

    public Student(String id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    //重写之后的equals方法 比较的就是对象内部的属性值
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(id, student.id) && Objects.equals(name, student.name) && Objects.equals(sex, student.sex);
    }

    //重写hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(id, name, sex);
    }

    //重写之后的toString方法 打印的是属性值
    @Override
    public String toString() {
        return  "学号:" + id  + ", 姓名:" + name + "("+sex+")";
    }
}
import java.util.*;

public class Test {
    public static void main(String[] args) {

        //测试toString equals方法
        Student s1 = new Student("202107","jh","m");
        Student s2 = new Student("202107","yy","f");
        //重写之后的toString() 打印的是内容
        System.out.println("s1.toString():"+s1.toString());
        System.out.println("s1.toString():"+s2.toString());
        //重写之后的equals方法 比较的是内容
        System.out.println("s1.equals(s2):"+s1.equals(s2));

        //1.创建一个链式集合
        LinkedList<Student> list = new LinkedList<>();

        //2.数组生成7个学生信息
        String[][] arrStu = {{"202101","张三","m"},{"202105","李四","m"},{"202101","张三","m"},
                {"202101","张三","m"},{"202103","王小","f"},{"202102","王小","f"},{"202105","李四","m"}};

        //3.生成学生对象 并且放入集合中
        for (int i = 0; i < arrStu.length; i++) {
            Student stu = new Student(arrStu[i][0],arrStu[i][1],arrStu[i][2]);
            list.add(stu);
        }

        //4.头部插入对象 并输出list对象信息
        Student s = new Student("202104","小七","f");
        list.add(0,s);
        list.forEach(str-> System.out.println(str));

        //5.学号序输出list对象信息
        list.sort((a,b)->a.getId().compareTo(b.getId()));
        System.out.println("--------idSort--------");
        list.forEach(str-> System.out.println(str));

        //6.创建一个set集合 接收数据 重写hashCode方法保证键值唯一
        Set<Student> set = new HashSet<>(list);
        System.out.println("----------Set---------");
        set.forEach(str-> System.out.println(str));
        //添加数据  返回值看是否添加成功
        Student stu = new Student("202101","张三","m");
        boolean result = set.add(stu);
        System.out.println("添加数据:"+result);
        //打印最终结果
        System.out.println("--------endSet--------");
        set.forEach(str-> System.out.println(str));
    }

}

输出内容:

s1.toString():学号:202107, 姓名:jh(m)
s1.toString():学号:202107, 姓名:yy(f)
s1.equals(s2):false
学号:202104, 姓名:小七(f)
学号:202101, 姓名:张三(m)
学号:202105, 姓名:李四(m)
学号:202101, 姓名:张三(m)
学号:202101, 姓名:张三(m)
学号:202103, 姓名:王小(f)
学号:202102, 姓名:王小(f)
学号:202105, 姓名:李四(m)
--------idSort--------
学号:202101, 姓名:张三(m)
学号:202101, 姓名:张三(m)
学号:202101, 姓名:张三(m)
学号:202102, 姓名:王小(f)
学号:202103, 姓名:王小(f)
学号:202104, 姓名:小七(f)
学号:202105, 姓名:李四(m)
学号:202105, 姓名:李四(m)
----------Set---------
学号:202101, 姓名:张三(m)
学号:202105, 姓名:李四(m)
学号:202104, 姓名:小七(f)
学号:202102, 姓名:王小(f)
学号:202103, 姓名:王小(f)
添加数据:false
--------endSet--------
学号:202101, 姓名:张三(m)
学号:202105, 姓名:李四(m)
学号:202104, 姓名:小七(f)
学号:202102, 姓名:王小(f)
学号:202103, 姓名:王小(f)

2.用到getOrDefault()方法的例题

Java中的Map_第1张图片

class Solution{
    public String evaluate(String s, List<List<String>> knowledge) {
        Map<String,String> mp = new HashMap();
        for(List<String> list:knowledge){
            mp.put(list.get(0),list.get(1));//添加键值对
        }
        StringBuilder sb = new StringBuilder();
        char[] ch = s.toCharArray();//这里将字符串对象中的字符转换为一个字符数组
        for(int i = 0,t;(t=i)<ch.length;i++){
            if(ch[i]=='('){
                while(ch[i]!=')') i++;
                sb.append(mp.getOrDefault(s.substring(t+1,i),"?"));//键值存在否 选择性添加
            }else{
                sb.append(ch[i]);
            }
        }
        return sb.toString();
    }
 }

3.较为综合的练习题

这一题充分展现了JAVA的”便捷“,不信你大可试试c/c++,说实话真的STL中map感觉比java好用多了,用java有时候还不如直接模拟哈希,写题自觉用c/c++Java中的Map_第2张图片

class Solution {
    public int rearrangeCharacters(String s, String target) {
        char[] sChar = s.toCharArray();//字符串转换为字符数组
        char[] tChar = target.toCharArray();//java字符串不同于c/c++ 不存在字符组成 需要特定方法charAt()获取 如果遍历次数过多这样转换可能好点

        //创建两个哈希表计数
        Map<Character,Integer> sCounts = new HashMap<>();
        Map<Character,Integer> tCounts = new HashMap<>();

        for(Character ch:tChar){
            tCounts.put(ch, tCounts.getOrDefault(ch, 0) + 1);//感觉很妙么 c++直接map[key]++
        }
        for(Character ch:sChar){
            if(tCounts.containsKey(ch)){//只有在target中出现的字符才会影响最大副本数
                sCounts.put(ch, sCounts.getOrDefault(ch, 0) + 1);
            }
        }
        int ans = Integer.MAX_VALUE;//记录副本数
        for (Map.Entry<Character, Integer> entry : tCounts.entrySet()) {//遍历记录
            char c = entry.getKey();//获取键
            int count = entry.getValue();//在target中出现次数
            int totalCount = sCounts.containsKey(c) ? sCounts.get(c) : 0;//如果s中根本不存在 则直接赋予0
            ans = Math.min(ans, totalCount / count);//所有字符对应的最大副本数中的最小值即为使用s中的字符可以形成的target的最大副本数
            if (ans == 0) {//如果ans等于零 则直接返回
                return 0;
            }
        }
        return ans;
    }
}

你可能感兴趣的:(JAVA,java,开发语言,算法)