Map 接口

Map 接口(重点)

​ 如果现在假设要操作一对对象,类似于以 下一种情况:

张三 123456

李四 234567

​ 保存以上信息的时候使用 Collection 就不那么方便,所以要使用 Map 接口。里面的所有内容都按照 key–>value 的形式保存,也称为二元偶对象。

此接口定义如下:

public interface Map<K,V>

此接口与 Collection 接口没有任何的关系,是第二大的集合操作接口。此接口常用方法如下:

No.方法名称类型描述
1void clear()普通清空 Map 集合中的内容
2boolean containsKey(Object key普通判断集合中是否存在指定的 key
3boolean containsValue(Object value)普通判断集合中是否存在指定的 value
4Set<Map.Entry<K,V>> entrySet()普通将 Map 接口变为 Set 集合
5V get(Object key)普通根据 key 找到其对应的 value
6boolean isEmpty()普通判断是否为空
7Set keySet()普通将全部的 key 变为 Set 集合
8Collection values()普通将全部的 value 变为 Collection 集合
9V put(K key,V value)普通向集合中增加内容
10void putAll(Map<? extends K, ? extends V> m)普通增加一组集合
11V remove(Object key)普通根据 key 删除内容

​ Map 本身是一个接口,所以一般会使用以下的几个子类:HashMap、TreeMap、Hashtable

新的子类:HashMap(重点

HashMap 是 Map 的子类,此类的定义如下:

public class HashMap<K,V> extends AbstractMap<K,V> 
implements Map<K,V>, Cloneable, Serializable

此类继承了 AbstractMap 类,同时可以被克隆,可以被序列化下来。

向集合中增加内容:

public class HashMapDemo01 {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "张三A");
        map.put(1, "张三B"); // 新的内容替换掉旧的内容
        map.put(2, "李四");
        map.put(3, "王五");
        String val = map.get(6);
        System.out.println(val);
    }
}

​ 以上的操作是 Map 接口在开发中最基本的操作过程,根据指定的 key 找到内容,如果没有找到,则返回 null,找到 了则返回具体的内容。

得到全部的 key 或 value :

public class HashMapDemo02 {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "张三A");
        map.put(2, "李四");
        map.put(3, "王五");
        Set<Integer> set = map.keySet(); // 得到全部的key
        Collection<String> value = map.values(); // 得到全部的value
        Iterator<Integer> iter1 = set.iterator();
        Iterator<String> iter2 = value.iterator();
        System.out.print("全部的key:");
        while (iter1.hasNext()) {
        	System.out.print(iter1.next() + "、");
        }
        System.out.print("\n全部的value:");
        while (iter2.hasNext()) {
        	System.out.print(iter2.next() + "、");
        }
    }
}

既然可以取得全部的 key,那么下面就可以对以上的操作进行扩充,循环输出 Map 中的全部内容。

public class HashMapDemo03 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("ZS", "张三");
        map.put("LS", "李四");
        map.put("WW", "王五");
        map.put("ZL", "赵六");
        map.put("SQ", "孙七");
        Set<String> set = map.keySet(); // 得到全部的key
        Iterator<String> iter = set.iterator();
        while (iter.hasNext()) {
        	String i = iter.next(); // 得到key
        	System.out.println(i + " --:> " + map.get(i));
        }
    }
}

HashMap 本身是属于无序存放的。

旧的子类:Hashtable(重点

Hashtable 是一个最早的 key–>value 的操作类,本身是在 JDK 1.0 的时候推出的。其基本操作与 HashMap 是类似的。

public class HashtableDemo01 {
    public static void main(String[] args) {
        Map<String, Integer> numbers = new Hashtable<String, Integer>();
        numbers.put("one", 1);
        numbers.put("two", 2);
        numbers.put("three", 3);
        Integer n = numbers.get("two");
        if (n != null) {
        	System.out.println("two = " + n);
        }
    }
}

​ 操作的时候,可以发现与 HashMap 基本上没有什么区别,而且本身都是以 Map 为操作标准的,所以操作的结果形式 都一样。但是 Hashtable 中是不能向集合中插入 null

HashMap 与 Hashtable 的区别(重点

在整个集合中除了 ArrayList 和 Vector 的区别之外,另外一个最重要的区别就是 HashMap 与 Hashtable 的区别。

No.区别点HashMapHastable
1推出时间JDK 1.2 之后推出的,新的操作类JDK 1.0 时推出的,旧的操作类
2性能异步处理,性能较高同步处理,性能较低
3null允许设置为 null不允许设置,否则将出现空指向异常

区别总结:

1.区别:
(1)HashMap方法没有synchronized修饰,线程非安全,HashTable线程安全;
(2)HashMap允许key和value为null,而HashTable不允许

2.底层实现:数组+链表实现

jdk8开始链表高度到8、数组长度超过64,链表转变为红黑树,元素以内部类Node节点存在

  • 计算key的hash值,二次hash然后对数组长度取模,对应到数组下标,
  • 如果没有产生hash冲突(下标位置没有元素),则直接创建Node存入数组,
  • 如果产生hash冲突,先进行equa比较,相同则取代该元素,不同,则判断链表高度插入链表,链表高度达到8,并且数组长度到64则转变为红黑树,长度低于6则将红黑树转回链表
  • key为null,存在下标0的位置

排序的子类:TreeMap(理解)

TreeMap 子类是允许 key 进行排序的操作子类,其本身在操作的时候将按照 key 进行排序,另外,key 中的内容可以 为任意的对象,但是要求对象所在的类必须实现 Comparable 接口。

public class TreeMapDemo01 {
    public static void main(String[] args) {
        Map<String, String> map = new TreeMap<String, String>();
        map.put("ZS", "张三");
        map.put("LS", "李四");
        map.put("WW", "王五");
        map.put("ZL", "赵六");
        map.put("SQ", "孙七");
        Set<String> set = map.keySet(); // 得到全部的key
        Iterator<String> iter = set.iterator();
        while (iter.hasNext()) {
        	String i = iter.next(); // 得到key
        	System.out.println(i + " --:> " + map.get(i));
        }
    }
}

​ 此时的结果已经排序成功了,但是从一般的开发角度来看,在使用 Map 接口的时候并不关心其是否排序,所以此类 只需要知道其特点即可。

关于 Map 集合的输出

​ 在 Collection 接口中,可以使用 iterator()方法为 Iterator 接口实例化,并进行输出操作,但是在 Map 接口中并没有此 方法的定义,所以 Map 接口本身是不能直接使用 Iterator 进行输出的。

​ 因为 Map 接口中存放的每一个内容都是一对值,而使用 Iterator 接口输出的时候,每次取出的都实际上是一个完整的 对象。如果此时非要使用 Iterator 进行输出的话,则可以按照如下的步骤进行: 1、 使用 Map 接口中的 entrySet()方法将 Map 接口的全部内容变为 Set 集合

​ 2、 可以使用 Set 接口中定义的 iterator()方法为 Iterator 接口进行实例化

​ 3、 之后使用 Iterator 接口进行迭代输出,每一次的迭代都可以取得一个 Map.Entry 的实例

​ 4、 通过 Map.Entry 进行 key 和 value 的分离

​ 那么,到底什么是 Map.Entry 呢?

​ Map.Entry 本身是一个接口。此接口是定义在 Map 接口内部的,是 Map 的内部接口。此内部接口使用 static 进行定义, 所以此接口将成为外部接口。

​ 实际上来讲,对于每一个存放到 Map 集合中的 key 和 value 都是将其变为了 Map.Entry 并且将 Map.Entry 保存在了 Map 集合之中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HzJSwCtM-1627353035723)(D:\typora\Typora\picture\image-20210721034835333.png)]

在 Map.Entry 接口中以下的方法最为常用:

No.方法名称类型描述
1K getKey()普通得到 key
2V getValue()普通得到 value

使用 Iterator 输出 Map 接口

public class MapOutDemo01 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("ZS", "张三");
        map.put("LS", "李四");
        map.put("WW", "王五");
        map.put("ZL", "赵六");
        map.put("SQ", "孙七");
        Set<Map.Entry<String, String>> set = map.entrySet();// 变为Set实例
        Iterator<Map.Entry<String, String>> iter = set.iterator();
        while (iter.hasNext()) {
            Map.Entry<String, String> me = iter.next();
            System.out.println(me.getKey() + " --> " + me.getValue());
        }
    }
}

​ 以上的代码一定要记住,Map 集合中每一个元素都是 Map.Entry 的实例,只有通过 Map.Entry 才能进行 key 和 value 的分离操作。

​ 除了以上的做法之外,在 JDK 1.5 之后也可以使用 foreach 完成同样的输出,只是这样的操作基本上不使用。

public class MapOutDemo02 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("ZS", "张三");
        map.put("LS", "李四");
        map.put("WW", "王五");
        map.put("ZL", "赵六");
        map.put("SQ", "孙七");
        for (Map.Entry<String, String> me : map.entrySet()) {
        	System.out.println(me.getKey() + " --> " + me.getValue());
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值