一篇文章带你搞定 Java 中 Map 接口的学习

文章目录

    • 一、Map 接口简介
    • 二、Map.Entry 接口简介
    • 三、 相关操作实例
      • 1. 实例操作一:向集合中增加和取出内容
      • 2. 实例操作二:判断指定的 key 或 value 是否存在
      • 3. 实例操作三:输出全部的 key
      • 4. 实例操作四:输出全部的 value
    • 四、排序的子类:TreeMap
    • 五、弱引用类:WeakHashMap
    • 六、Map 接口的使用注意事项
      • 1. 不能直接使用迭代输出 Map 的全部内容
        • (1)使用 Iterator 输出 Map 实例
        • (2)使用 foreach 输出 Map 实例
      • 2. 直接使用非系统类作为 key
    • 七、key 可以重复的 Map 集合:IdentityHashMap

一、Map 接口简介

Collection、Set、List 接口都属于单值的操作,即每次只能操作一个对象,而 Map 与每次操作的是一对对像,即二元偶对象,Map 中的每个元素都使用 key->value 的形式存储在集合中。
Map 接口的定义:

public interface Map<K,V>

在 Map 上也应用了泛型,必须同时设置好 key 或 value 的类型,在 Map 中每一对
key -> value都表示一个值。Map 接口中方法:
一篇文章带你搞定 Java 中 Map 接口的学习_第1张图片

二、Map.Entry 接口简介

Map.Entry 是 Map 内部定义的一个接口,专门用来保存 key->value 的内容。定义如下:

public static interface Map.Entry<K,V>

Map.Entry 是使用 static 关键字声明的内部接口,此接口可以由外部通过“外部类.内部类”的形式直接调用。
Map.Entry 接口的常用方法:
一篇文章带你搞定 Java 中 Map 接口的学习_第2张图片
在 Map 操作中,所有的内容都是通过 key->value 的形式保存数据,对于集合来讲实际上是将 key->value 的数据保存在 Map.Entry 的实例之后,再在 Map 集合中插入的是一个 Map.Entry 的实例化对象:
一篇文章带你搞定 Java 中 Map 接口的学习_第3张图片
Map.Entry在集合输出时会使用到

三、 相关操作实例

如果要想使用 Map 接口也必须依靠其子类实例化,Map接口中常用的子类:

HashMap:无序存放,是新的操作类,key 不允许重复
Hashtable:无序存放,是旧的操作类,key 不允许重复
TreeMap:可以排序的 Map 集合,按集合中的 key 排序,key 不允许重复
WeakHashMap:弱引用的 Map 集合,当集合中的某些内容不再使用时清除掉无用的数据,使用 gc 进行回收
IdentifyHashMap:key 可以重复的 Map 集合

HashMap 本身是 Map 的子类,直接使用此类为 Map 接口实例化即可

1. 实例操作一:向集合中增加和取出内容

在 Map 接口中可以使用 put(Object key,Object value) 方法向集合中增加内容,之后可以使用 get(E key) 方法根据 key 找出其对应的 value。

public class Root{
    public static void main(String[] args) {
        Map<String,String > map = new HashMap<String, String>();//实例化 map
        map.put("1","Java");
        map.put("2","Python");
        String val = map.get("2");//根据 key 求出 value
        System.out.println("取出的内容是:" + val);
    }
}

2. 实例操作二:判断指定的 key 或 value 是否存在

如果要判断某一个指定的额 key 或 value 是否存在,可以使用 Map 接口中提供的 containsKey(Object key) 和 containsValue(Object value) 两个方法,前者判断Map集合是否存在指定的 key,后者判断 Map 集合是否存在指定的 value

public class Root{
    public static void main(String[] args) {
        Map<String,String > map = new HashMap<String, String>();//实例化 map
        map.put("1","Java");
        map.put("2","Python");
        if (map.containsKey("1")) {
            System.out.println("搜索的 key 存在!");
        }
        if (map.containsValue("Python")) {
            System.out.println("搜索的 Value 存在!");
        }
    }
}

3. 实例操作三:输出全部的 key

在 Map 中提供了一个叫做 keySet() 的方法,可以将一个 Map 中的全部 key 变为一个 Set 集合,一旦有了 Set 实例,就可以直接使用 Iterator 输出。但是在进行操作时一定要注意接收的 Set 集合中指定的泛型要和 Map 中的key的泛型类型保持一致

public class Root{
    public static void main(String[] args) {
        Map<String,String > map = new HashMap<String, String>();//实例化 map
        map.put("1","Java");
        map.put("2","Python");
        Set<String > keys = map.keySet();//得到全部的 key
        Iterator<String> iter = keys.iterator();
        System.out.print("全部的 key:");
        while (iter.hasNext()){
            String  str = iter.next();
            System.out.print(str + "、");
        }
    }
}

4. 实例操作四:输出全部的 value

如果要输出全部的 value,则使用 values() 方法,此方法的返回类型是 Collection,在进行操作时也同样需要注意泛型的类型

public class Root{
    public static void main(String[] args) {
        Map<String,String > map = new HashMap<String, String>();//实例化 map
        map.put("1","Java");
        map.put("2","Python");
        Collection<String > values = map.values();//得到全部的 key
        Iterator<String> iter = values.iterator();
        System.out.print("全部的 value:");
        while (iter.hasNext()){
            String  str = iter.next();
            System.out.print(str + "、");
        }
    }
}

四、排序的子类:TreeMap

TreeMap 的主要功能是按 key 排序

import java.util.*;

public class Root{
    public static void main(String[] args) {
        Map<String,String > map = new TreeMap<String, String>();//实例化 map
        map.put("2","Java");
        map.put("1","Python");
        map.put("3","Html");
        Set<String > keys = map.keySet();//得到全部的 key
        Iterator<String> iter = keys.iterator();
        while (iter.hasNext()){
            String  str = iter.next();
            System.out.println(str + " --> " + map.get(str));//取出 key 对应的内容
        }
    }
}

一篇文章带你搞定 Java 中 Map 接口的学习_第4张图片
这里需要注意使用自定义类作为 key 类需要实现 Comparable 接口
因为程序中国使用的是String作为 key ,因为String 本身已经实现了 Comparable 接口,所以可以直接执行,而如果使用一个自定义的类作为 key,则此类必须实现 Comparable 接口,否则将出现类转换异常。

五、弱引用类:WeakHashMap

无论是 HashMap 还是TreeMap 都是使用强引用保存的,即里面的内容不管是否使用都始终在集合中保留,如果希望集合自动清理暂时不用的数据就使用 WeakHashMap类。这样当进行垃圾收集时会释放掉集合中的垃圾信息
WeakHashMap 的定义:

public class WeakHashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>
public class Test{
    public static void main(String[] args) {
        Map<String,String > map = new WeakHashMap<String, String>();//实例化 map
        map.put("2","Java");
        map.put(new String("1"),new String("Python"));
        System.gc();//进行垃圾收集
        map.put("3","Html");
        System.out.println("内容:" + map);
        }
}

一篇文章带你搞定 Java 中 Map 接口的学习_第5张图片
可以看出使用 map.put()的方式不同,会达到不同的强引用和弱引用效果

六、Map 接口的使用注意事项

1. 不能直接使用迭代输出 Map 的全部内容

对于 Map 接口来说,其本身是不能直接使用迭代(Iterator、foreach)进行输出的,因为 Map 中的每个位置存放的是一对值(key->value),而 Iterator 中每次只能找到一个值
所以,如果非要使用迭代进行输出,必须按照以下步骤(以 Iterator 输出方法为例):
(1)将 Map 的实例通过 entrySet() 方法变为 Set 接口
(2)通过 Set 接口实例为 Iterator 实例化
(3)通过 Iterator 迭代输出,每个内容都是 Map.Entry 的对象
(4)通过 Map.Entry 进行 key->value 的分离

Map 一般很少直接输出,只是作为查询使用,而 Collection 接口在开发中主要作用是传递内容及输出。

(1)使用 Iterator 输出 Map 实例

public class Test{
    public static void main(String[] args) {
        Map<String,String > map = new HashMap<String, String>();//实例化 map
        map.put("2","Java");
        map.put("1","Python");
        map.put("3","Html");
        Set<Map.Entry<String ,String >> allSet = null;//声明一个 Set 集合,指定泛型
        allSet = map.entrySet();//将 Map 接口实例变为 Set 接口实例
        Iterator<Map.Entry<String ,String >> iter = null;//声明 Iterator 对象
        iter = allSet.iterator();//实例化 Iterator 对象
        while (iter.hasNext()){
            Map.Entry<String ,String > me = iter.next();//找到 Map.Entry 实例
            System.out.println(me.getKey() + "-->" + me.getValue());//输出 key 和 value
        }
        }
}

一篇文章带你搞定 Java 中 Map 接口的学习_第6张图片

(2)使用 foreach 输出 Map 实例

public class Test{
    public static void main(String[] args) {
        Map<String,String > map = new HashMap<String, String>();//实例化 map
        map.put("2","Java");
        map.put("1","Python");
        map.put("3","Html");
        for (Map.Entry<String ,String> me:map.entrySet()){//输出 Set 集合
            System.out.println(me.getKey() + "-->" + me.getValue());
        }
        }
}

2. 直接使用非系统类作为 key

如果使用一个自定义的对象表示 Map 中的 key,则对象所在的类中一定要覆写 equals() 和 hashCode() 方法,否则无法找到对应的 value

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

class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    public boolean equals(Object obj){//覆写 equals() 方法
        if (this ==obj){
            return true;
        }
        if (!(obj instanceof Person)){//传递进来的不是本类的对象
            return false;
        }
        Person p = (Person)obj;
        if (this.name.equals(p.name) && this.age == p.age){
            return true;//属性依次比较,相等返回
        }else {
            return false;
        }
    }
    public int hashCode(){//覆写 hashCode() 方法
        return this.name.hashCode() * this.age;//计算公式
    }
    public String toString(){
        return "姓名" + this.name + ";年龄:" + this.age;//返回信息
    }
}
public class Test{
    public static void main(String[] args) {
        Map<Person,String> map = null;
        map = new HashMap<Person,String >();//实例化 Map 对象
        Person per = new Person("Java",30);
        map.put(per,"Python");
        System.out.println(map.get(per));
    }
}

七、key 可以重复的 Map 集合:IdentityHashMap

前面所述的 Map 操作中 key 的值是不能重复的,如果重复会覆盖之前的内容,此时可以使用 IdentityHashMap,使用此类只有地址不相等(key1 != key2),就表示不是重复的 key,可以添加到集合中。

public class Test{
    public static void main(String[] args) {
        Map<Person,String> map = new IdentityHashMap<Person,String >();
        map.put(new Person("张三",30),"J1");
        map.put(new Person("李四",31),"J2");
        map.put(new Person("李四",31),"J3");
        map.put(new Person("王二",32),"J4");
        Set<Map.Entry<Person,String >> allSet = null;//声明一个 Set 集合
        allSet = map.entrySet();//将 Map 接口实例为 Set 接口实例
        Iterator<Map.Entry<Person,String >> iter = null;
        iter = allSet.iterator();//实例化 Iterator 对象
        while (iter.hasNext()){
            Map.Entry<Person,String > me = iter.next();//每个对象都是 Map.Entry 实例
            System.out.println(me.getKey() + "-->" + me.getValue());//输出 key 和 value
        }
    }
}

你可能感兴趣的:(Java,学习笔记,java,Map,接口)