Java--Map集合

掌握每个Map集合底层采用什么数据结构存储数据,优缺点是什么,熟练使用集合对象的相关方法。


Map集合

  • Map集合和Collection集合没有继承关系
  • Map集合以key和value这种键值对存储数据。key和value只能存储引用,存储对象的内存地址。key起主导作用,value是key的一个附属品。在Map集合中有一个内部类Node,key和value是内部类的两个属性

Map集合继承结构

map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable等。其中这区别如下(简单介绍):

HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。

TreeMap: 能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。

Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。

在这里插入图片描述

Map接口中的通用方法

Map接口中的方法是Map集合公用的,有以下方法:

  • V put(K key,V value);添加元素。

  • V get(Object key);根据键获取值

  • void clear();移除所有的键值对元素

  • V remove(Object key);根据键删除键值对元素,并把值返回

  • boolean containsKey(Object key);判断集合是否包含指定的键

  • boolean containsValue(Object value);判断集合是否包含指定的值

  • boolean isEmpty();判断集合是否为空

  • Set<Map.Entry<K,V>> entrySet();把map集合转换为set集合,set集合中每个元素是Map.Entry类型,Map.Entry对象包含key,value

  • Set keySet();获取集合中所有键的集合,返回一个Set集合

  • Collection values();获取Map集合中所有的value,返回一个Collection集合

编写程序,熟悉运用

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

//Map集合常用方法
public class Test01 {
    public static void main(String[] args) {

        //创建map集合对象
        Map<Integer,String> map = new HashMap<>();
        //put方法添加键值对
        map.put(1,"张三");
        map.put(2,"李四");
        map.put(3,"王五");
        map.put(4,"lic");
        //通过key获取对应的value
        System.out.println("key为1对应的value是:"+map.get(1));
        //获取键值对的数量
        System.out.println("键值对的数量是:"+map.size());
        //通过key删除键值对
        //System.out.println(map.remove(1));
        //判断集合中是否包含这个key
        System.out.println("是否包含1这个key "+map.containsKey(1));
        //判断集合中是否包含这个value
        System.out.println("是否包含李四这个value "+map.containsValue("李四"));
        //获取所有的value 返回Collection集合
        Collection<String> values = map.values();

        for (String a:values
             ) {
            System.out.println(a);
        }

        //获取所有的key 返回Map集合
        Set<Integer> keySet = map.keySet();

        for (Integer k:keySet
             ) {
            System.out.print(k);
        }
        //判断是否为空
        System.out.println(map.isEmpty());
        
        //清空集合
        map.clear();

    }
}

Map集合四种遍历

获取Map集合所有的key,返回Set集合,一种foreach遍历

//Map集合的遍历
        //方法一:foreach
        //获取map集合所有的key值 返回set集合

        for (Integer in:map.keySet()) {

            System.out.println(in+"="+map.get(in));  //通过key获取value

        }

一种迭代器遍历

 //方法二:迭代器

        Set<Integer> values = map.keySet();
        Iterator<Integer> iterator = values.iterator();
        while (iterator.hasNext()){
            Integer next = iterator.next();
            System.out.println(next+"="+map.get(next));
        }

Map集合转换成Set集合,set集合元素是Map.Entry对象,通过getKey()、getvalue()方法,再进行foreach遍历

//Map集合转换成Set集合,set集合元素是Map.Entry对象,foreach遍历
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry.getKey()+"="+entry.getValue());
        }

Map集合转换成Set集合,set集合元素是Map.Entry对象,通过getKey()、getvalue()方法,再进行迭代器遍历

 //Map集合转换成Set集合,set集合元素是Map.Entry对象,迭代器遍历
        Set<Map.Entry<Integer, String>> entries = map.entrySet();
        Iterator<Map.Entry<Integer, String>> entryIterator = entries.iterator();
        while (entryIterator.hasNext()){
            Map.Entry<Integer, String> next = entryIterator.next();
            System.out.println(next.getKey()+"="+next.getValue());
        }

HashMap集合

HashSet集合底层是HashMap,HashMap集合底层采用哈希表存储数据,哈希表的数据结构是数组和链表的结合体,集数组的检索便利和链表的插入便利优点于一体。哈希表的随机增删在链表上,查询在数组,所以哈希表效率较高。

在这里插入图片描述

put、get方法实现原理

put方法实现原理:

1.将k,value封装到Node对象中;

2.调用k的hashCode方法返回hash值,然后通过哈希函数,将hash值转换成数组的下标,对应下标没有元素,就把Node添加进去,如果对应的位置有元素,则用k和元素链表上的k进行equals,返回false,将node添加到末尾,返回true,进行覆盖,把新的value赋值。

get方法实现原理:

1.调用k的hashCode方法返回hash值

2.通过哈希函数,将hash值转换成数组的下标,通过数组下标进行位置定位,若该位置什么也没有,返回null,若该位置有链表,则用这个k和链表上的k进行equals,若返回false,则get方法返回null,返回true,则返回这个链表节点上的value。

注意:
两个方法在使用时,底层都是先调用hashCode方法,再调用equals方法。
同时重写hashCode方法、equals方法。

示例HashMap,自定义类作为key、value:

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

public class HashMapTest {
    public static void main(String[] args) {
        //创建对象
        HashMap<Integer,String> hashMap = new HashMap<>();
        //添加元素  key重复时 value会覆盖
        Person a = new Person(1, "张三");
        Person b = new Person(2, "小白");
        Person c = new Person(3, "李四");
        Person d = new Person(4, "李翰");

        hashMap.put(a.id,a.name);
        hashMap.put(b.id,b.name);
        hashMap.put(c.id,c.name);
        hashMap.put(d.id,d.name);
        //键值对的数量
        System.out.println(hashMap.size());
        //集合遍历
        for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
            System.out.println(entry);
        }
        //取出元素
        System.out.println(hashMap.get(2));

    }
}
class Person{
    int id;
    String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    //重写equals hashCode方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

Hashtable

Hashtable中的方法都带有synchronized:线程安全。线程安全有其他的方案, Hashtable对线程处理效率低

Hashtable初始化容量:

在这里插入图片描述

Hashtable扩容:

在这里插入图片描述
Hashtable中的key、value不允许为null, HashMap的key、value允许为null。

Properties类

Properties是Map集合,继承 Hashtable,key、value都是String类型。称为属性类。

import java.util.Properties;

public class Test04 {
    public static void main(String[] args) {
        Properties p  = new Properties();
        //存
        p.setProperty("a","asd");
        p.setProperty("s","ddn");
        p.setProperty("d","oin");
        //取
        System.out.println(p.getProperty("a"));
        System.out.println(p.getProperty("s"));
        System.out.println(p.getProperty("d"));
    }
}

TreeMap集合

继承Collection接口的Set集合的实现类TreeSet底层实际是TreeMap集合,TreeMap集合底层采用二叉树数据结构,存时采取左小右大原则,遍历时采取中序遍历(左根右)

在这里插入图片描述
示例方法:

import java.util.Map;
import java.util.TreeMap;

public class TreeMapTest {
    public static void main(String[] args) {
        TreeMap<Integer, String> map = new TreeMap<>();
        map.put(1,"李三");
        map.put(8,"张三");
        map.put(2,"李四");
        map.put(3,"王麻子");
        map.put(5,"李翰");

        //返回与大于或等于给定键元素的最小键元素链接的键值对
        System.out.println(map.ceilingEntry(4));  //5=李翰

        //返回与大于或等于给定键元素的最小键元素链接的键值
        System.out.println(map.ceilingKey(4));

        //修改key的value
        System.out.println(map.replace(8, "小马"));
        System.out.println(map.get(8));

        //遍历
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry);
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值