Java学习笔记(三十六)—— Map 集合(接口)

概述

Map<K,V>,K - 由此地图维护的键的类型,V - 映射值的类型
        将键映射到值的对象。 地图不能包含重复的键; 每个键可以映射到最多一个值。 该接口代替了Dictionary类,它是一个完全抽象的类而不是接口。
        Map接口提供了三个集合视图 ,允许将映射的内容视为一组键,值的集合或键值映射集合。 地图的顺序被定义为其中在地图上的集合视图迭代返回元素的顺序。 一些地图实现,如TreeMap类,对其顺序做出特定的保证; 其他人,像HashMap类,不要。

特点
  1. 双列集合,一个元素包含两个值(一个时key,一个时value)
  2. key和value的数据类型可以相同,也可以不同
  3. key不允许重复,value可以重复
  4. key和value是一一对应的
常用实现类
  1. HashMap
            基于哈希表的实现的Map接口。 该实现提供了所有可选的映射操作,并允许null值和null密钥。 ( HashMap类大致相当于Hashtable ,除了它是不同步的,并允许null)。这个类不能保证地图的顺序; 特别是,它不能保证订单在一段时间内保持不变。

    特点
    	I、底层是哈希表:查询速度特快
    	II、无序集合,存储元素与取出元素的顺序可能不同
    	III、是一个线程不安全的集合,多线程集合
    

    1.1 HashMap子类LinkedHashMap
            哈希表和链表实现的Map接口,具有可预测的迭代顺序。 该实现与HashMap不同之处在于它保持双向链接列表的所有条目。 此链接列表定义迭代排序,通常是将键插入到地图( 插入顺序 )中的顺序 。 请注意,如果将键重新插入到地图中,则插入顺序不受影响。 (A键k被重新插入到地图m如果m.put(k, v)时被调用m.containsKey(k)将返回true之前立即调用。)

    I、底层是哈希表+链表(保证迭代的顺序)
    II、是有序的集合
    
        HashMap<String,String> map = new HashMap<>();
        map.put("a","a1");
        map.put("c","c1");
        map.put("b","b1");
        map.put("d","d1");
        System.out.println(map); // {a=a1, b=b1, c=c1, d=d1}

        LinkedHashMap<String,String> link=new LinkedHashMap<>();
        link.put("a","a1");
        link.put("c","c1");
        link.put("b","b1");
        link.put("d","d1");
        System.out.println(link); // {a=a1, c=c1, b=b1, d=d1}
  1. Hashtable
    2.1 概述:
            该类实现了一个哈希表,它将键映射到值。 任何非null对象都可以用作键值或值。
            要从哈希表成功存储和检索对象,用作键的对象必须实现hashCode方法和equals方法。
            Hashtable一个实例有两个参数影响其性能: 初始容量和负载因子 。 容量是哈希表中的桶数, 初始容量只是创建哈希表时的容量。 请注意,哈希表是打开的 :在“哈希冲突”的情况下,单个存储桶存储多个条目,必须依次搜索。 负载因子是在容量自动增加之前允许哈希表得到满足的度量。初始容量和负载因子参数仅仅是实现的暗示。 关于何时以及是否调用rehash方法的具体细节是依赖于实现的。
            从Java 2平台v1.2开始,该类进行了改进,实现了Map接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Hashtable被同步。 如果不需要线程安全的实现,建议使用HashMap代替Hashtable 。 如果需要线程安全高度并发的实现,那么建议使用ConcurrentHashMap代替Hashtable 。

    2.2 特点

    I、底层是哈希表,是一个线程安全的集合,是单线程集合,速度慢
    II、不能存储null值和null键
    
            HashMap<String, String> map = new HashMap<>();
        map.put(null,null);
        System.out.println(map);// {null=null}
    
        Hashtable<String, String> table = new Hashtable<>();
        table.put(null,"dddd"); // 报错:NullPointerException
        table.put("dd",null); // 报错:NullPointerException
    
常用方法
  1. put​(K key, V value),将指定的值与该映射中的指定键相关联(可选操作)。
/*
    返回值:
        key不重复,返回null
        key重复,返回被替换的value值

 */

        Map<String,String> map=new HashMap<>();
        map.put("a","a1");
        map.put("b","b1");
        System.out.println(map); // {a=a1, b=b1}
        System.out.println(map.put("b","b2")); // b1
        System.out.println(map); // {a=a1, b=b2}
        System.out.println(map.put("c","c1")); // null
        System.out.println(map); // {a=a1, b=b2, c=c1}
  1. get​(Object key),返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null 。
System.out.println(map.get("a")); // a1
System.out.println(map.get("d")); // null
  1. remove​(Object key),如果存在(从可选的操作),从该地图中删除一个键的映射。
        System.out.println(map.remove("c")); // c1
        System.out.println(map.remove("d")); // null
        System.out.println(map); // {a=a1, b=b2}
  1. containsKey​(Object key),如果此映射包含指定键的映射,则返回 true 。.
        System.out.println(map.containsKey("b")); // true
        System.out.println(map.containsKey("c")); // false
  1. entrySet​(),返回此地图中包含的映射的Set视图。
System.out.println(map.entrySet()); // [a=a1,b=b1]
  1. keySet​(),返回此地图中包含的键的Set视图。
System.out.println(map.keySet()); // [a,b]
  1. get​(Object key),返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null 。
System.out.println(map.get("a")); // a1
System.out.println(map.get("d")); // null
Entry键值对对象
  1. 概述:在Map接口中有一个内部接口Entry。当Map集合中创建,就会在Map集合中创建一个Entry对象,用来记录键与值
  2. Entry对象中的方法
    2.1 getKey()获取key值
    2.2 getValue() 获取value值
        Map<String,Integer> map=new HashMap<>();
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        var set = map.entrySet();
        var it = set.iterator();
        while (it.hasNext()){
            Map.Entry<String, Integer> next = it.next();
            System.out.println(next.getKey());
            System.out.println(next.getValue());
        }
存储自定义类型键值
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 +
                '}';
    }
}

        Map<String,Student> map=new HashMap<>();
        map.put("beijing",new Student("zhangsan",18));
        map.put("shanghai",new Student("lisi",19));
        map.put("guangzhou",new Student("wangwu",12));
        map.put("beijing",new Student("zhaoliu",8));
        // {shanghai=Student{name='lisi', age=19}, guangzhou=Student{name='wangwu', age=12}, beijing=Student{name='zhaoliu', age=8}}
        System.out.println(map);
public class Person {
        private String name;
        private int age;

        public Person() {
        }

        public Person(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 "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                name.equals(person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
		// Map集合存储自定义类作为键,那么改类必须重写hashCode()和equals()方法,才能保证键不重复
        Map<Person,String> map=new HashMap<>();
        map.put(new Person("zhangsan",18),"China");
        map.put(new Person("lisi",19),"America");
        map.put(new Person("zhangsan",18),"England");
        // {Person{name='lisi', age=19}=America, Person{name='zhangsan', age=18}=England}
        System.out.println(map); 
练习
// 计算一个字符串中每次字符出现次数

        // 获取用户输入的字符串
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str=sc.next();

        // 创建Map集合
        var map= new HashMap<Character, Integer>();

        // 获取每一字符,并存入Map集合中
        for (char c:str.toCharArray()){
            if(map.containsKey(c)){
                Integer value=map.get(c);
                value++;
                map.put(c,value);
            }else{
                map.put(c,1);
            }
        }
        // 输出结果
        System.out.println(map);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值