Map三大实现类详细解析(附代码)

博主之前学习了map的接口以及底层实现原理,但是后面又忘记,用的时候比较困惑,所以回来重新整理,涵盖了Map基础,未整理hashmap线程不安全,分段锁这一块。

1.常用的实现类结构

Map:双列数据 存储使用key—value对的数据   类似y = f(x)----hashMap:主要实现类 线程不安全 效率高 可以存储null的key和value
​				----LinkHashMap:可以按照添加顺序实现遍历
​					原因:在底层结构基础上,添加了一对指针,指向前一个后一个元素,如果频繁的遍历,推荐使用。
​			----SortedMap----TreeMap:对key实现了自然排序或者定制排序
​			----Hashtable:最老的实现类,线程安全,效率底,不能存储null的key和value
​				----properties:常用来处理配置文件,String:key value
​		【面试题】、
​			1.hashmap和hashtable的异同
​			答:效率线程安全、keyvalue能否null、子类的功能

2.Map的存储结构

key:使用set存储 无序的不可重复的 -->所在类需要重写hashcode和qeuals
value:使用collection存储 无序 可重复 -->所在类重写equals方法
Map中的entry:<key,value>是一个entry(键值对) 使用set存储

3.HashMap内存结构说明

####  3.1 jdk1.7HashMap map = new HashMap();
​      map.put(key1,value1)....
​	  map.put(keyn,valuen)
​	实例化之后,底层创建长度16一维数组Entry[] table;执行put时,首先通过key所在类的hashcode()得hash值,通过某种算法得到在Entry数组的存储位置,如果此位置为空,直接添加。位置不为空,比较Hash值,值不同,添加。如果值相同,调用equals,如果相同,直接覆盖value值,相当于修改,如果不同,进行添加。
注意:在数组相同位置上进行添加的时候,以链表的方式存储。添加过程中,超过临界值,数组扩大两倍
临界值的计算:初始大小*负载因子  默认16 * 0.75=12


####  3.2 jdk1.8与jdk1.7的不同
​	1.new HashMap(): 未创建容量16的底层数组
​	2.jdk8的底层数字组的Node[]3.调用put的时候开始创建长度是16的数组
​	4.1.7的底层结构是数组+链表 1.8:数组+链表+红黑树
​	5.形成链表时 七上八下(7:新的指向旧的 8:旧的指向新的)
​	6.当数组的某一个索引以链表形式存在的数据个数>8  数组的长度>64 采用红黑树

4.方法

  • 添加:put(Object key,Object value)
  • 删除:remove(Object key)
  • 修改:put(Object key,Object value)
  • 查询:get(Object key)
  • 长度:size()
  • 遍历:keySet() / values() / entrySet()

实现代码

准备类

public class User implements Comparable{
    String name;
    int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;

        User user = (User) o;

        if (getAge() != user.getAge()) return false;
        return getName() != null ? getName().equals(user.getName()) : user.getName() == null;
    }

    @Override
    public int hashCode() {
        int result = getName() != null ? getName().hashCode() : 0;
        result = 31 * result + getAge();
        return result;
    }

    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;
    }

    public User() {
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof  User){
            User user = (User)o;
            return Integer.compare(this.age,user.age);
        }else {
            throw new RuntimeException("类型不匹配");
        }
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

HashTree的实现类

import org.junit.Test;

import java.util.*;

public class HashTreeTest {
    //根据传入类进行自然排序(年龄小到大)
    @Test
    public void test1(){
        TreeMap map = new TreeMap();
        User u1 = new User("TOM1", 19);
        User u2 = new User("TOM2", 18);
        User u3 = new User("TOM3", 22);
        User u4= new User("TOM4", 16);
        map.put(u1,90);
        map.put(u2,80);
        map.put(u3,100);
        map.put(u4,89);
        Set entrySet = map.entrySet();
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()){
            Object obj = iterator.next();
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey());

        }
    }
    //自制排序 年龄大到小
    @Test
    public void test2(){
        TreeMap map = new TreeMap((Object o1,Object o2)->{
            User u1 = (User)o1;
            User u2 = (User)o2;
            return -Integer.compare(u1.getAge(),u2.getAge());
        });
        User u1 = new User("TOM1", 19);
        User u2 = new User("TOM2", 18);
        User u3 = new User("TOM3", 22);
        User u4= new User("TOM4", 16);
        map.put(u1,90);
        map.put(u2,80);
        map.put(u3,100);
        map.put(u4,89);
        Set entrySet = map.entrySet();
        for (Object o : entrySet) {
            Map.Entry entry = (Map.Entry) o;
            System.out.println(entry.getKey());

        }
    }

}

properties实现类

import java.io.FileInputStream;

import java.io.IOException;

public class Properties {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            java.util.Properties pros = new java.util.Properties();

            fis = new FileInputStream("jdbc.properties");
            pros.load(fis);

            String name = pros.getProperty("name");
            String password = pros.getProperty("password");

            System.out.println("name = " + name + ", password = " + password);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布丁味

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值