java中Map集合的理解

Map<K,V>集合的特点: K用来限制键的类型,V用来限制值的类型
       1.Map集合是以键值对的形式存储数据,每个键值对都有键和值
       2.Map集合中的键是唯一的,值是可以重复的,如果键重复了,值就会覆盖
       3.根据键取值

Map集合子类:
     HashMap:存储数据采用的结构是哈希表结构,所以不能保证键值对存取有序,可以保证键唯一
         	由哈希表保证键唯一,所以键所属的类需要重写hashCode和equals方法
         
     LinkedHashMap:存储数据采用的结构是链表+哈希表结构,由链表保证键值对存取有序,由哈希表保证键唯一
         	由哈希表保证键唯一,所以键所属的类需要重写hashCode和equals方法
         
     TreeMap:存储数据采用的是红黑树结构,可以保证键唯一,并且可以对键进行排序
         	public TreeMap(); 按照默认规则排序
            public TreeMap(Comparator<? super K> comparator): 按照指定规则排序

知识点-- Map的常用方法

目标

  • 使用Map的常用方法

路径

  • 代码演示

讲解

Map接口中定义了很多方法,常用的如下:

  • public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。
  • public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
  • public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
  • public boolean containsKey(Object key):判断该集合中是否有此键
  • public boolean containsValue(Object value):判断该集合中是否有此值
  • public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
  • public Collection<V> values(): 获取Map集合中所有的值,存储到Set集合中。
  • public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。

Map接口的方法演示

public class Test {
    public static void main(String[] args) {
        /*
            Map<K,V>的常用方法:
                - public V put(K key, V value):  把指定的键与指定的值添加到Map集合中。
                - public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
                - public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
                - public boolean containsKey(Object key):判断该集合中是否有此键
                - public boolean containsKey(Object value):判断该集合中是否有此值
                - public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
                - public Collection<V> values(): 获取Map集合中所有的值,存储到Set集合中。
                - public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的 键值对对象 的集合(Set集合)。
                键值对对象: Entry<K,V>接口类型来表示
                由于Entry<K,V>接口是Map接口的成员内部接口,所以外界要使用的时候,需要这么写:Map.Entry<K,V>

                Set<String>   字符串对象  String
                Set<Map.Entry<K,V>>         键值对对象  Map.Entry<K,V>
         */
        // 创建Map集合,限制键的类型为String,值的类型为String类型
        Map<String, String> map = new HashMap<>();

        // 往map集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");

        System.out.println("map:"+map);// {文章=马伊琍, 谢霆锋=王菲, 黄晓明=杨颖}

        // 验证: 键唯一,如果键重复了,值会覆盖
        map.put("文章", "姚笛");
        System.out.println("map:"+map);// {文章=姚笛, 谢霆锋=王菲, 黄晓明=杨颖}

        // 验证: 值可以重复
        map.put("李亚鹏", "王菲");
        System.out.println("map:"+map);// {文章=姚笛, 谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖}

        // 需求:删除李亚鹏这个键对应的键值对
        String removeV = map.remove("李亚鹏");
        System.out.println("被删除键的值:"+removeV);// 王菲
        System.out.println("map:"+map);// {文章=姚笛, 谢霆锋=王菲, 黄晓明=杨颖}

        // 需求: 获取文章这个键对应的值
        String value1 = map.get("文章");
        System.out.println("value1:"+value1);// 姚笛

        // 需求:判断是否有谢霆锋这个键
        System.out.println(map.containsKey("谢霆锋"));// true
        // 需求:判断是否有李亚鹏这个键
        System.out.println(map.containsKey("李亚鹏"));// false

        // 需求:判断是否有姚笛这个值
        System.out.println(map.containsValue("姚笛"));// true
        // 需求:判断是否有马伊琍这个值
        System.out.println(map.containsValue("马伊琍"));// false

        // 需求:获取map集合中所有的键
        Set<String> keys = map.keySet();
        System.out.println("所有的键:"+keys);// [文章, 谢霆锋, 黄晓明]

        // 需求:获取map集合中所有的值
        Collection<String> values = map.values();
        System.out.println("所有的值:"+values);// [姚笛, 王菲, 杨颖]

        // 需求:获取map集合中所有 键值对对象
        Set<Map.Entry<String, String>> entrys = map.entrySet();
        System.out.println(entrys);// [文章=姚笛, 谢霆锋=王菲, 黄晓明=杨颖]
    }
}

tips:

使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;

若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。

String putV = map.put("邓超", "孙俪");
        System.out.println("putV:"+putV);// null

        String putValue = map.put("谢霆锋", "张柏芝");
        System.out.println("putValue:"+putValue);// 王菲

知识点–Map的遍历

目标

  • 使用Map的遍历

路径

  • 方式1:键找值方式
  • 方式2:键值对方式

讲解

方式1:键找值方式

通过元素中的键,获取键所对应的值

分析步骤:

  1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:keyset()
  2. 遍历键的Set集合,得到每一个键。
  3. 根据键,获取键所对应的值。方法提示:get(K key)
public class Test1_方式一 {
    public static void main(String[] args) {
        /*
            根据键找值:
                1.获取map集合所有的键  keySet()方法
                2.遍历所有的键
                3.根据键找值          get(K k)方法

         */
        // 创建Map集合,限制键的类型为String,值的类型为String类型
        Map<String, String> map = new HashMap<>();

        // 往map集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");

        // 1.获取map集合所有的键  keySet()方法
        Set<String> keys = map.keySet();

        // 2.遍历所有的键
        for (String key : keys) {
            // 3.根据键找值          get(K k)方法
            String value = map.get(key);
            System.out.println("key:"+key+",value:"+value);
        }
    }
}
方式2:键值对方式
Entry<K,V>接口:简称Entry项,表示键值对对象,用来封装Map集合中的键值对
Entry<K,V>接口:是Map接口中的内部接口,在外部使用的时候是这样表示: Map.Entry<K,V>

Map集合中提供了一个方法来获取所有键值对对象:
            public Set<Map.Entry<K,V>> entrySet()

根据键值对对对象获取键和值:
            - public K getKey():获取Entry对象中的键。
            - public V getValue():获取Entry对象中的值。

Map遍历方式二:根据键值对对象的方式
            1.获取集合中所有键值对对象,以Set集合形式返回。  Set<Map.Entry<K,V>> entrySet()
            2.遍历所有键值对对象的集合,得到每一个键值对(Entry)对象。
            3.在循环中,可以使用键值对对对象获取键和值   getKey()和getValue()
public class Test2_方式二 {
    public static void main(String[] args) {
        /*
            键值对方式:
                1.获取map集合的所有键值对对象   entrySet()方法
                2.循环遍历所有的键值对对象
                3.根据键值对对象去获取键和值

            键值对对象: Entry<K,V>接口类型来表示
            由于Entry<K,V>接口是Map接口的成员内部接口,所以外界要使用的时候,需要这么写:Map.Entry<K,V>
            Entry<K,V>接口中的方法:
                    K getKey();  获取键值对对象的键
                    V getValue();获取键值对对象的值
         */
        // 创建Map集合,限制键的类型为String,值的类型为String类型
        Map<String, String> map = new HashMap<>();

        // 往map集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");

        // 1.获取map集合的所有键值对对象   entrySet()方法
        Set<Map.Entry<String, String>> entrys = map.entrySet();

        // 2.循环遍历所有的键值对对象
        for (Map.Entry<String, String> entry : entrys) {
            // 3.根据键值对对象去获取键和值
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println("key:"+key+",value:"+value);
        }

    }
}

知识点-- HashMap存储自定义类型

目标

  • 使用HashMap存储自定义类型

路径

  • 代码演示

讲解

练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。

注意,学生姓名相同并且年龄相同视为同一名学生。

编写学生类:

public class Student {
    public String name;// 姓名
    public int age;// 年龄

    public Student(String name, int age) {
        this.name = name;
        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);
    }
}

编写测试类:

public class Test {
    public static void main(String[] args) {
        /*
            练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。
                 学生作为键, 家庭住址作为值。
                 注意,学生姓名相同并且年龄相同视为同一名学生。
         */
        // 创建HashMap集合,限制键的类型为Student,值的类型为String
        HashMap<Student, String> map = new HashMap<>();

        // 创建学生对象
        Student stu1 = new Student("张三",18);
        Student stu2 = new Student("李四",19);
        Student stu3 = new Student("王五",17);
        Student stu4 = new Student("张三",18);

        // 往集合中添加键值对
        map.put(stu1, "北京");
        map.put(stu2, "上海");
        map.put(stu3, "深圳");
        map.put(stu4, "广州");

        // 循环遍历集合
        Set<Student> keys = map.keySet();
        for (Student key : keys) {
            String value = map.get(key);
            System.out.println("key:"+key+",value:"+value);
        }
    }
}
  • 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
  • 如果要保证map中存放的key和取出的顺序一致,可以使用java.util.LinkedHashMap集合来存放。

知识点–LinkedHashMap介绍

目标

  • 我们知道HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?

路径

  • LinkedHashMap

讲解

  • 通过链表结构可以保证元素的存取顺序一致;
  • 通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
public class Test {
    public static void main(String[] args) {
        /*
            LinkedHashMap集合特点:键值对存取有序,键唯一,值可以重复,如果键重复了,值就会覆盖
                由于是由哈希表保证键唯一,所以如果键是自定义类型的类,那么必须重写hashCode和equals方法
         */
        // 创建LinkedHashMap集合,限制键的类型为String,值的类型为String
        LinkedHashMap<String, String> map = new LinkedHashMap<>();

        // 往集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");
        map.put("李亚鹏", "王菲");
        map.put("文章", "姚笛");


        // 打印集合
        System.out.println(map);// {黄晓明=杨颖, 文章=姚笛, 谢霆锋=王菲, 李亚鹏=王菲}
    }
}

知识点–TreeMap集合

目标

  • 使用TreeMap集合

路径

  • TreeMap介绍
  • 构造方法

讲解

TreeMap介绍

TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;可以对元素的**进行排序,排序方式有两种:自然排序比较器排序;到时使用的是哪种排序,取决于我们在创建对象的时候所使用的构造方法;

构造方法
public TreeMap()									使用自然排序
public TreeMap(Comparator<? super K> comparator) 	   通过比较器指定规则排序
案例演示
public class Test {
    public static void main(String[] args) {
        /*
            TreeMap集合的特点:可以对键值对进行排序,键唯一,值可以重复,如果键重复了,值就会覆盖
            TreeMap集合的构造方法:
                public TreeMap()									使用默认规则排序
                如果键是自定义类型的类,那么该类需要实现Comparable接口,重写compareTo方法,指定排序规则
                public TreeMap(Comparator<? super K> comparator) 	通过比较器指定规则排序
         */
        // 默认规则排序: 升序
        // 创建TreeMap集合,限制键的类型为Integer,值的类型为String
        TreeMap<Integer, String> map = new TreeMap<>();

        // 往集合中添加键值对
        map.put(300, "刘德华");
        map.put(100, "张学友");
        map.put(200, "郭富城");
        map.put(500, "黎明");
        map.put(400, "梁朝伟");
        map.put(400, "古天乐");
        map.put(600, "古天乐");

        // 打印集合
        System.out.println(map);


        System.out.println("=======================================");

        // 指定规则排序: 降序
        // 创建TreeMap集合,限制键的类型为Integer,值的类型为String
        TreeMap<Integer, String> map2 = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        // 往集合中添加键值对
        map2.put(300, "刘德华");
        map2.put(100, "张学友");
        map2.put(200, "郭富城");
        map2.put(500, "黎明");
        map2.put(400, "梁朝伟");
        map2.put(400, "古天乐");
        map2.put(600, "古天乐");

        // 打印集合
        System.out.println(map2);

    }
}

案例-- Map集合练习

需求

  • 输入一个字符串中每个字符出现次数。

分析

  • 获取一个字符串对象
  • 创建一个Map集合,键代表字符,值代表次数。
  • 遍历字符串得到每个字符。
  • 判断Map中是否有该键。
  • 如果没有,第一次出现,存储次数为1;如果有,则说明已经出现过,获取到对应的值进行++,再次存储。
  • 打印最终结果

实现

方法介绍

public boolean containKey(Object key):判断该集合中是否有此键。

代码:

public class Test {
    public static void main(String[] args) {
        // 1.键盘录入一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String str = sc.nextLine();

        // 2.创建Map集合,限制键的类型为Character,值的类型为Integer
        Map<Character, Integer> map = new HashMap<>();

        // 3.循环遍历该字符串
        for (int i = 0; i < str.length(); i++) {
            // 4.在循环中,获取遍历出来的字符
            char c = str.charAt(i);

            // 5.在循环中,判断该字符在Map集合中是否已经作为了键
            if (map.containsKey(c)) {
                // 6.如果已经作为了键,那么就取出该键对应的值,然后让该值+1,作为新的值,存储到Map集合中
                Integer value = map.get(c);
                value++;
                map.put(c,value);

            } else {
                // 6.如果没有作为键,那么该字符作为键,值为1,存储到Map集合中
                map.put(c,1);
            }
        }
        // 7.打印map集合的键值对
        System.out.println(map);
    }
}

第四章 集合的嵌套

  • 总述:任何集合内部都可以存储其它任何集合

知识点–集合的嵌套

目标

  • 理解集合的嵌套

路径

  • List嵌套List
  • List嵌套Map
  • Map嵌套Map

讲解

List嵌套List
public class Test1 {
    public static void main(String[] args) {
        /*
            集合的嵌套:
                - List嵌套List
                - List嵌套Map
                - Map嵌套Map
            结论:任何集合内部都可以存储其它任何集合
         */
        //  List嵌套List
        // 创建一个List集合,限制元素类型为String
        List<String> list1 = new ArrayList<>();

        // 往集合中添加元素
        list1.add("王宝强");
        list1.add("贾乃亮");
        list1.add("陈羽凡");

        // 创建一个List集合,限制元素类型为String
        List<String> list2 = new ArrayList<>();

        // 往集合中添加元素
        list2.add("马蓉");
        list2.add("李小璐");
        list2.add("白百何");

        // 创建一个List集合,限制元素类型为List集合 (List集合中的元素是List集合)
        List<List<String>> list = new ArrayList<>();
        list.add(list1);
        list.add(list2);

        // 遍历
        for (List<String> e : list) {
            for (String name : e) {
                System.out.println(name);
            }
            System.out.println("=============");
        }

        System.out.println(list);
    }
}
List嵌套Map
public class Test2 {
    public static void main(String[] args) {
        /*
            List嵌套Map:

         */
        // 创建Map集合对象
        Map<String,String> map1 = new HashMap<>();
        map1.put("it001","迪丽热巴");
        map1.put("it002","古力娜扎");

        // 创建Map集合对象
        Map<String,String> map2 = new HashMap<>();
        map2.put("heima001","蔡徐坤");
        map2.put("heima002","李易峰");

        // 创建List集合,用来存储以上2个map集合
        List<Map<String,String>> list = new ArrayList<>();
        list.add(map1);
        list.add(map2);

        System.out.println(list.size()); // 2

        for (Map<String, String> map : list) {
            // 遍历获取出来的map集合对象
            Set<String> keys = map.keySet();// 获取map集合所有的键
            // 根据键找值
            for (String key : keys) {
                System.out.println(key + ","+ map.get(key));
            }
        }

    }
}
Map嵌套Map
public class Test3_Map嵌套Map {
    public static void main(String[] args) {
        /*
            Map嵌套Map:

         */
        // 创建Map集合对象
        Map<String, String> map1 = new HashMap<>();
        map1.put("it001", "迪丽热巴");
        map1.put("it002", "古力娜扎");

        // 创建Map集合对象
        Map<String, String> map2 = new HashMap<>();
        map2.put("heima001", "蔡徐坤");
        map2.put("heima002", "李易峰");

        // 创建Map集合,把以上2个Map集合作为值存储到这个map集合中
        Map<String, Map<String, String>> map = new HashMap<>();

        // 往map集合中添加键值对
        map.put("itheima", map1);
        map.put("itcast", map2);

        // 获取map集合所有的键
        Set<String> keys = map.keySet();

        // 循环遍历所有的键
        for (String key : keys) {
            // 根据键找值
            Map<String, String> stringMap = map.get(key);
            //System.out.println(key + ":" + stringMap);
            // 获取stringMap集合所有的键
            Set<String> keySet = stringMap.keySet();
            // 循环遍历所有的键
            for (String k : keySet) {
                // 根据键找值
                String v = stringMap.get(k);
                System.out.println(k+"="+v);
            }

            System.out.println("===================");
        }


    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 2集合框架图  集合接口:6个接口(短虚线表示),表示不同集合类型,是集合框架的基础。  抽象类:5个抽象类(长虚线表示),对集合接口的部分实现。可扩展为自定义集合类。  实现类:8个实现类(实线表示),对接口的具体实现。  在很大程度上,一旦您理解了接口,您就理解了框架。虽然您总要创建接口特定的实现,但访问实际集合的方法应该限制在接口方法的使用上;因此,允许您更改基本的数据结构而不必改变其它代码。  · Collection 接口是一组允许重复的对象。  · Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制。  · List 接口继承 Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。  · Map接口是一组成对的键-值对象,即所持有的是key-value pairs。Map不能有重复的key。拥有自己的内部排列机制。  · 容器的元素类型都为Object。从容器取得元素时,必须把它转换成原来的类型。  Java 2简化集合框架图  集合接口  1.Collection 接口  用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时,就使用这一接口。  (1) 单元素添加、删除操作:   boolean add(Object o):将对象添加给集合   boolean remove(Object o): 如果集合有与o相匹配的对象,则删除对象o  (2) 查询操作:   int size() :返回当前集合元素的数量   boolean isEmpty() :判断集合是否有任何元素   boolean contains(Object o) :查找集合是否含有对象o

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值