map接口的讲解

目录

Map接口特点

Map接口和常用方法

Map接口遍历方法

Map接口练习

HashMap小结


Map接口特点

Map接口实现类的特点

注意:这里是JDK8的Map接口特点 

  1. Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value

  2. Map中的key和value 可以是任何引用类型的数据,会封装到HashMap$Node对象中

  3. Map中的 key不允许重复,原因和HashSet一样,前面分析过源码.

  4. Map中的 value 可以重复

  5. Map的key可以为null,value也可以为null,注意 key为null,只能有一个,value为null,可以多个.

  6. 常用String类作为Map的 key

  7. key和 value之间存在单向一对一关系,即通过指定的 key总能找到对应的value

代码演示:

注意在map接口中,是按照k-v的形式来存放数据的,即就是键值对,我们可以根据key找到对应的value

package idea.chapter14.map_;


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

@SuppressWarnings({"all"})
public class Map_ {
    public static void main(String[] args) {
        //Map 接口实现类的特点, 使用实现类HashMap
        //1. Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value(双列元素)
        //2. Map 中的 key 和  value 可以是任何引用类型的数据,会封装到HashMap$Node 对象中
        //3. Map 中的 key 不允许重复,原因和HashSet 一样,前面分析过源码.
        //4. Map 中的 value 可以重复
        //5. Map 的key 可以为 null, value 也可以为null ,注意 key 为null,只能有一个,value 为null ,可以多个
        //6. 常用String类作为Map的 key
        //7. key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value
        Map map = new HashMap();
        map.put("1", "jack");//k-v
        map.put("2", "tom");//k-v
        map.put("1", "mary");//当有相同的k , 就等价于替换.
        map.put("3", "smith");//k-v
        map.put(null, null); //k-v
        map.put(null, "abc"); //等价替换
        map.put("4", null); //k-v
        map.put("5", null); //k-v
        map.put(new Object(), "你好");//k-v
        // 通过get 方法,传入 key ,会返回对应的value
        System.out.println(map.get("2"));//tom

        System.out.println("map=" + map);


    }
}

8.Map存放数据的key-value示意图,一对 k-v是放在一个HashMap$Node中的,有因为Node实现了 Entry接口

代码演示:

package idea.chapter14.map_;

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

@SuppressWarnings({"all"})
public class MapSource_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("1", "jack");//k-v
        map.put("2", "tom");//k-v
        map.put(new Car(), new Person());//k-v
        
        //1. k-v 最后是 HashMap$Node node = newNode(hash, key, value, null)
        //2. k-v 为了方便程序员的遍历,还会 创建 EntrySet 集合 ,该集合存放的元素的类型 Entry, 而一个Entry
        //   对象就有k,v EntrySet<Entry<K,V>> 即: transient Set<Map.Entry<K,V>> entrySet;
        //3. entrySet 中, 定义的类型是 Map.Entry ,但是实际上存放的还是 HashMap$Node
        //   这时因为 static class Node<K,V> implements Map.Entry<K,V>
        //4. 当把 HashMap$Node 对象 存放到 entrySet 就方便我们的遍历, 因为 Map.Entry 提供了重要方法
        //   K getKey(); V getValue();

        Set set = map.entrySet();
        System.out.println(set.getClass());// HashMap$EntrySet
        for (Object obj : set) {

            //System.out.println(obj.getClass()); //HashMap$Node
            //为了从 HashMap$Node 取出k-v
            //1. 先做一个向下转型
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() + "-" + entry.getValue() );
        }

        Set set1 = map.keySet();
        System.out.println(set1.getClass());
        Collection values = map.values();
        System.out.println(values.getClass());
    }
}

class Car {

}

class Person{

}

Map接口和常用方法

1.put:添加

2.remove:根据键删除映射关系

3.get:根据键获取值

4.size:获取元素个数

5.isEmpty:判断个数是否为0

6.clear:清除

7.containsKey:查找键是否存在

代码演示:

package idea.chapter14.map_;

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

@SuppressWarnings({"all"})
public class MapMethod {
    public static void main(String[] args) {
        //演示map接口常用方法

        Map map = new HashMap();
        map.put("邓超", new Book("", 100));//OK
        map.put("邓超", "孙俪");//替换-> 一会分析源码
        map.put("王宝强", "马蓉");//OK
        map.put("宋喆", "马蓉");//OK
        map.put("刘令博", null);//OK
        map.put(null, "刘亦菲");//OK
        map.put("鹿晗", "关晓彤");//OK

        System.out.println("map=" + map);

//        remove:根据键删除映射关系
        map.remove(null);
        System.out.println("map=" + map);
//        get:根据键获取值
        Object val = map.get("鹿晗");
        System.out.println("val=" + val);
//        size:获取元素个数
        System.out.println("k-v=" + map.size());
//        isEmpty:判断个数是否为0
        System.out.println(map.isEmpty());//F
//        clear:清除k-v
        //map.clear();
        System.out.println("map=" + map);
//        containsKey:查找键是否存在
        System.out.println("结果=" + map.containsKey("hsp"));//T


    }
}

class Book {
    private String name;
    private int num;

    public Book(String name, int num) {
        this.name = name;
        this.num = num;
    }
}

Map接口遍历方法

  1. containsKey:查找键是否存在

  2. keySet:获取所有的键

  3. entrySet:获取所有关系k-v

  4. values:获取所有的值

代码演示:

package idea.chapter14.map_;

import java.util.*;

@SuppressWarnings({"all"})
public class MapFor {
    public static void main(String[] args) {

        Map map = new HashMap();
        map.put("1", "jack");//k-v
        map.put("2", "tom");//k-v
        map.put("1", "mary");//当有相同的k , 就等价于替换.
        map.put("3", "smith");//k-v
        map.put(null, null); //k-v

        //第一组: 先取出 所有的Key , 通过Key 取出对应的Value
        Set keyset = map.keySet();
        //(1) 增强for
        System.out.println("-----第一种方式-------");
        for (Object key : keyset) {
            System.out.println(key + "-" + map.get(key));
        }
        //(2) 迭代器
        System.out.println("----第二种方式--------");
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            System.out.println(key + "-" + map.get(key));
        }

        //第二组: 把所有的values取出
        Collection values = map.values();
        //这里可以使用所有的Collections使用的遍历方法
        //(1) 增强for
        System.out.println("---取出所有的value 增强for----");
        for (Object value : values) {
            System.out.println(value);
        }
        //(2) 迭代器
        System.out.println("---取出所有的value 迭代器----");
        Iterator iterator2 = values.iterator();
        while (iterator2.hasNext()) {
            Object value = iterator2.next();
            System.out.println(value);

        }

        //第三组: 通过EntrySet 来获取 k-v
        Set entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>>
        //(1) 增强for
        System.out.println("----使用EntrySet 的 for增强(第3种)----");
        for (Object entry : entrySet) {
            //将entry 转成 Map.Entry
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "-" + m.getValue());
        }
        //(2) 迭代器
        System.out.println("----使用EntrySet 的 迭代器(第4种)----");
        Iterator iterator3 = entrySet.iterator();
        while (iterator3.hasNext()) {
            Object entry = iterator3.next();
            //System.out.println(next.getClass());//HashMap$Node -实现-> Map.Entry (getKey,getValue)
            //向下转型 Map.Entry
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "-" + m.getValue());
        }


    }
}

Map接口练习

代码演示:

注意事项:

1.在使用增强for遍历时

//注意转成emp类型时,转的时value,并不是key 如果转的是key,会报类型转换异常 所以我们这里通过hashMap的get方法得到key对应的值,然后进行向下转型
2.使用迭代器遍历时
// 在转成emp类型时,转的时value,并不是key 如果转的是key,会报类型转换异常 所以我们这里
//先将其转成Map.Entry类型 然后使用Entry中提供的getValue()方法,直接获取到值,不在需要key来得到对应的值
package idea.chapter14.map_;

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

/*
使用HashMap添加3个员工对象,要求
键:员工id
值:员工对象
并遍历显示工资>18000的员工(遍历方式最少两种)员工类:姓名、工资、员工id
 */
@SuppressWarnings({"all"})
public class MapExercise {
    public static void main(String[] args) {
        Map hashMap = new HashMap();
        //添加数据
        hashMap.put(1, new Emp("jack", 300000, 1));
        hashMap.put(2, new Emp("tom", 21000, 2));
        hashMap.put(3, new Emp("milan", 12000, 3));

        //遍历2种方式
        //并遍历显示工资>18000的员工
        //1. 使用keySet  -> 增强for
        Set keySet = hashMap.keySet();
        System.out.println("====第一种遍历方式====");
        for (Object key : keySet) {
            //先获取value
            //注意转成emp类型时,转的时value,并不是key 如果转的是key,会报类型转换异常 所以我们这里通过hashMap的get方法得到key对应的值,然后进行向下转型
            Emp emp = (Emp) hashMap.get(key);
            if (emp.getSalary() > 18000) {
                System.out.println(emp);
            }
        }

        //2. 使用EntrySet -> 迭代器
        Set entrySet = hashMap.entrySet();
        System.out.println("======迭代器======");
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            //这里也同理 
            // 在转成emp类型时,转的时value,并不是key 如果转的是key,会报类型转换异常 所以我们这里
            //先将其转成Map.Entry类型 然后使用Entry中提供的getValue()方法,直接获取到值,不在需要key来得到对应的值
            
            //通过entry 取得key 和 value
            Emp emp = (Emp) entry.getValue();
            if (emp.getSalary() > 18000) {
                System.out.println(emp);
            }
        }
    }
}

class Emp {
    private String name;
    private double salary;
    private int id;


    public Emp(String name, double salary, int id) {
        this.name = name;
        this.salary = salary;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", salary=" + salary +
                '}';
    }
}

HashMap小结

1.Map接口的常用实现类:HashMap、Hashtable和Properties。

2.HashMap是Map接口使用频率最高的实现类。

3.HashMap是以 key-val对的方式来存储数据(HashMap$Node类型)[案例Entry]

4)key 不能重复,但是值可以重复,允许使用null键和null值。

5)如果添加相同的key,则会覆盖原来的key-val,等同于修改.(key不会替换,val会替换)

6)与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.(jdk8的hashMap底层 数组+链表+红黑树)

7)HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值