铂西学习日记---Map

import java.util.*;

public class MapDemo {
    /**
     *
     Map接口:
     * 1、键值对存储一-组对象
     * 2、Key不能重复(唯一),Value可以重复
     * 3、具体的实现类: HashMap LinkedHashMap Hashtable TreeMap
     *
     * 4、如何选择?
     * 单线程?多线程?有序遍历? 按照一定顺序储存?......Hashtable用的比较少...
     *
     * 数据结构:数组、链表、二叉树、哈希表(数组+链表+二叉树)、栈、队列...
     *
     **/
    public static void main(String[] args) {
//        hashMap();
        TreeMap();
    }

    /**
     * HashMap --- 不能保证顺序恒久不变因为散列会重新打乱顺序
     * 1.实现原理:数组+链表+二叉树(红黑树)JDK1.8
     * 2.默认初始容量16,默认加载因子为0.75(意思就是若16个空间存了12个就不能存了,就得扩充)
     * 3.存储原理:先把key对象通过hash()方法计算hash值,然后用这个hash数组对数组长度取余(来决定这个键值对在数组中存储的位置),
     * 当这个位置为多个时变为链表,当链表长度大于等于8时就将这个链表变成一个红黑树结构存储,这样的目的是为了取值时更快。
     * 4.扩充原理:当数组存储的数据超过75%时,当前数组的容量就左移一位(*2),其实就是原来的二倍,然后再去将原来的所有元素重新计算存储位置(耗性能,也是弊端),
     * 所以扩充次数过多,就会很耗性能,因为每次扩充都得全部重新 ‘散列’,即重新计算每个元素的存储位置,所以在开发中药尽量减少扩充次数带来的性能问题。
     * 5.线程不安全,适合在单线程中使用
     */
    public static void hashMap(){
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"lsq");
        map.put(2,"lsw");
        map.put(3,"lse");
        System.out.println(map.size());

        //通过KEY取值
        System.out.println(map.get(1));

        //遍历 key+value
        Set<Map.Entry<Integer, String>> entries = map.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            System.out.println(entry.getKey()+": "+entry.getValue());
        }

        //遍历 key
        Set<Integer> keys = map.keySet();
        for (Integer key : keys) {
            System.out.println(key);
        }

        //遍历 value
        Collection<String> values = map.values();
        for (String value : values) {
            System.out.println(value);
        }

        //foreach进行遍历 key+value
        map.forEach((key,value)-> System.out.println("KEY->"+key+",VALUE->"+value));

        //是否包含key或value
        System.out.println(map.containsKey(5) ? "存在":"不存在");
        System.out.println(map.containsValue("lsq") ? "存在":"不存在");
        /**
         * 此外还有根据key删除键值对
         * 根据key替换值
         * ....更多方法查看API
         */
    }

    /**
     * Hashtable --- JDK1.0就开始了
     * 和HashMap差不多,基于哈希表实现(数组+链表),
     * 默认容量11,默认加载因子为0.75,
     * 扩充方式:原数组大小左移一位再加一,就是*2+1
     * 线程安全
     * 1.与 HashMap 的区别?
     */
    public static void hashTable(){
        Map<String,String> map = new Hashtable<>();
        map.put("one","lsq");
        map.put("two","lsw");
        map.put("three","lse");
        map.forEach((key,value)-> System.out.println("KEY->"+key+",VALUE->"+value));
    }

    /**
     * LinkedHashMap --- 继承了HashMap实现了接口
     * 它具有可预知的迭代顺序。此实现与HashMap的不同之处在于,后者维护着-一个运行于所有条目的双重链接列表,意思就是无论你怎么散列,我都维护着一个永恒不变的顺序
     */
    public static void linkedHashMap(){
        Map<String,String> map = new LinkedHashMap<>();
        map.put("one","lsq");
        map.put("two","lsw");
        map.put("three","lse");
        map.forEach((key,value)-> System.out.println("KEY->"+key+",VALUE->"+value));
    }

    /**
     * TreeMap --- TreeSet就是基于它实现的
     * 基于红黑树(一种平衡二叉树)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的Comparator进行排序,具体取决于使用的构造方法。
     */
    public static void TreeMap(){
        Map<String,String> map = new TreeMap<>();
        map.put("one","lsq");
        map.put("two","lsw");
        map.put("three","lse");
        map.forEach((key,value)-> System.out.println("KEY->"+key+",VALUE->"+value));

        Map<animal,String> tree = new TreeMap<>();
        tree.put(new animal("lsq",27),"cat1");
        tree.put(new animal("lsw",21),"cat2");
        tree.put(new animal("lse",29),"cat3");

        /**
         * 此处应当注意 --- 替换问题
         */
        tree.put(new animal("lsq",29),"CAT");//因为以age属性排序,若age相同,就会用后者全部替换

        tree.forEach((key,value)-> System.out.println("KEY->"+key+",VALUE->"+value));
    }

    /**
     * 跟多点击查看源码和API接口文档......
     */
}

class animal implements Comparable<animal>{
    private String name;
    private int age;

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

    public animal() {
    }

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

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

    @Override
    public int hashCode() {
        return Objects.hash(name, 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 int compareTo(animal o) {
        //根据年龄排序
        return this.age - o.age;
    }
}

JDK1.8下的Map中的新接口

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

public class newMapDemo {
    /**
     * Map接口JDK1.8新增方法介绍
     * @param args
     */
    public static void main(String[] args) {
        newMap();
    }

    /**
     * JDK1.8新增了接口的默认方法,接口内直接实现的方法,继承就有
     */
    public static void newMap(){
        Map<Integer, String> map = new HashMap<>();
        map.put(1,"one");
        map.put(2,"two");
        map.put(3,"three");

        /**
         * getOrDefault --- 获取不到key时返回一个默认值
         *
         *     default V getOrDefault(Object key, V defaultValue) {
         *         V v;
         *         return (((v = get(key)) != null) || containsKey(key))
         *             ?
         *             v : defaultValue;
         *     }
         */
        String s = map.get(4);
        System.out.println(s);
        String s2 = map.getOrDefault(4, "没有此键值对哦!");
        System.out.println(s2);

        /**
         * putIfAbsent --- 只会添加不存在的key的键值对 key值存在就返回之前的值,不存在再调用put()方法,返回null
         *
         *     default V putIfAbsent(K key, V value) {
         *         V v = get(key);
         *         if (v == null) {
         *             v = put(key, value);
         *         }
         *         return v;
         *     }
         */
        String getMapKeyEquals3 = map.put(3, "new three");
        System.out.println(getMapKeyEquals3);//结果是字符串'three',返回的是覆盖前的值
        System.out.println(map.get(3));//结果是字符串'new three',因为同一个key值被覆盖了
        String new_new_three = map.putIfAbsent(3, "new new three");
        System.out.println(new_new_three);//结果是字符串'new three',因为这个key值已存在
        String new_new_new_three = map.putIfAbsent(4, "four");
        System.out.println(new_new_new_three);//结果是null,因为这个key值不存在,调用了put()方法,并返回了null
        System.out.println(map.get(4));//结果是字符串'four'
        map.forEach((k,v)-> System.out.println(k+v));

        /**
         * remove(key,value),只有key和value都和集合中的一项键值对相同时才调用remove(key)方法,删除并返回true,否则返回false
         * 相对于remove(key)更加严谨了
         *
         *     default boolean remove(Object key, Object value) {
         *         Object curValue = get(key);
         *         if (!Objects.equals(curValue, value) ||
         *             (curValue == null && !containsKey(key))) {
         *             return false;
         *         }
         *         remove(key);
         *         return true;
         *     }
         */
        System.out.println(map.remove(4,"not four"));//结果是false
        System.out.println(map.remove(4,"four"));//结果是true

        /**
         * replace(k,v)
         * replace(k,v,v)
         * 先判断key不为空,且存在,都是调用的put(k,v),直接覆盖。
         */
        map.replace(3,"3");
        System.out.println(map.get(3));
        map.replace(3,"3","new-3");
        System.out.println(map.get(3));

        /**
         * compute --对某一key值进行计算
         * computeIfAbsent -- 如果key为null,将计算后的结果作为value再调用put(k,v)
         */
        map.compute(1,(k,v)->v+"test");
        System.out.println(map.get(1));
        map.computeIfAbsent(4,k->k+"test2");
        System.out.println(map.get(4));

        /**
         * merge -- 合并参数
         * default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction)
         *
         */
        map.merge(1,"onetest",(ov,nv)->ov.concat(nv));
        System.out.println(map.get(1));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小狗铂西

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

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

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

打赏作者

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

抵扣说明:

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

余额充值