Map集合,(HashMap,LinkedHashMap,TreeMap,)

Map集合

Map集合图解

在这里插入图片描述

Map集合常用子类

Map(接口):所有双列集合的“父接口”,它内部定义了所有“双列集合”所应该具有的所有方法。

  1. HashMap(子类):“键”是“哈希表结构”——无序、不重复。
  2. LinkedHashMap(子类):“键”是“链表 + 哈希表结构”——有序、不重复
  3. TreeMap(子类):“键”是“红黑树”——排序、不重复
    注意:Map的子类的“数据结构”都是应用在“键”上。
    “键”不能重复,但“值”可以重复。

Map集合常用方法:

  1. 增,改:
    public V put(K key, V value):向集合中添加一个键值对。

     关于返回值:
     	1,正常添加键值对:返回null
     		System.out.println(map.put("金蟾童子","唐三藏"));//null
     	2,如果添加的键值对的键(key)在集合中已经存在了,就会用新值替换掉原值,并返回原值。
     		System.out.println(map.put("金蟾童子","牛魔王"));//唐三藏(会用牛魔王替换掉唐三藏,返回值是:唐三藏)。
    
  2. 删:

    1. public void clear();//清空集合中所有元素。
    2. public V remove (Object key);//把指定的键所对应的键值对元素在Map集合中删除,并返回删除元素的值。
  3. 改(put)

  4. 查:

    1. public V get(Object key):根据指定的键,在Map集合中获取对应的值。
    2. public Set keySet();//获取Map集合中的所有值,存储到Set集合中。《遍历》
    3. public Set<Map.Entry<K,V>> entrySet();//获取Map集合中所有键值对对象的集合(Set集合)。《遍历》
    4. public boolean containsKey(Object key);//判断该集合中是否存在键。
    5. 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);
        }
    }
}

两种方式遍历的示意图:

在这里插入图片描述

两种方式的区别

  1. 第一种方式:要先将Map中所有“键”封装到一个Set中;然后再遍历所有“键的集合”,然后再通过“每个键”,再去Map中找“值”;
    写法简单【常用】
  2. 第二种方式:先将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的基本使用

  1. 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集合的基本使用:

  1. 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) + " 次");

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值