1.Map概述

        Map被称为双列集合,典型的key,value结构,Map集合有如下特点:

                1.Map集合的键和值都可以为空,但在同一个集合中键为null的只能有一个,值为null的可以有多个

                2.Map集合具有一对一的映射关系,即可以由相应的键得到相应的值

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

                4.Map中的key不允许重复,value可以重复

                5.常用String类作为Map集合的Key

                6.因为每对key,value都是存放在Node节点中的,又因为Node实现了Entry接口,故每对key,value又可以说是一个Entry,每个Entry放在EntrySet中,就组成了EntrySet集合,如下图所示:

java 最简单定义map java定义一个map集合_java

2.Map接口方法

        2.1 size()方法

        

java 最简单定义map java定义一个map集合_java_02

        2.2 isEmpty()方法

java 最简单定义map java定义一个map集合_java_03

        2.3 containsKey(Object key)

java 最简单定义map java定义一个map集合_java_04

        2.4 containsValues(Object value)

java 最简单定义map java定义一个map集合_java 最简单定义map_05

        2.5 put(Object key,Object value)

java 最简单定义map java定义一个map集合_java_06

        2.6 remove(Object key)

java 最简单定义map java定义一个map集合_System_07

        2.7 putAll(Map<? extends Object,? extends Object >)

java 最简单定义map java定义一个map集合_java 最简单定义map_08

        2.8 clear()

java 最简单定义map java定义一个map集合_开发语言_09

        2.9 keySet()

java 最简单定义map java定义一个map集合_java_10

        2.10 values()

java 最简单定义map java定义一个map集合_数组_11

        2.11 entrySet()

java 最简单定义map java定义一个map集合_java_12

        2.12 get(Object key)

java 最简单定义map java定义一个map集合_java_13

3.Map六大遍历方式

package com.company.hashmap;

import javafx.beans.binding.ObjectExpression;

import java.util.*;

public class HashMapDemo2 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        hashMap.put(1,new Employee("张三",18000.0,1));
        hashMap.put(2,new Employee("张三",18100.0,2));
        hashMap.put(3,new Employee("张三",18101.0,3));
        Collection values = hashMap.values();
        // 增强for循环遍历value
        System.out.println("增强for循环遍历value");
        for(Object employee : values){
            Employee employee1 = (Employee)employee;
            Double salary = employee1.getSalary();
            if(salary > 18000){
                System.out.println(employee1);

            }

        }
        // 迭代器遍历values
        System.out.println("迭代器遍历values");
        Iterator iterator = values.iterator();
        while (iterator.hasNext()){
            Employee next = (Employee)iterator.next();
            Double salary = next.getSalary();
            if(salary > 18000){
                System.out.println(next);

            }

        }
        // 增强for循环遍历key
        System.out.println("增强for循环遍历key");
        Set set = hashMap.keySet();
        for(Object employee : set){
            Integer key = (Integer) employee;
            Employee employee1 = (Employee) hashMap.get(key);
            Double salary = employee1.getSalary();
            if(salary > 18000){
                System.out.println(employee1);
            }

        }
        // 迭代器遍历key
        System.out.println("迭代器遍历key");
        Iterator iterator1 = set.iterator();
        while (iterator1.hasNext()){
            Object next = iterator1.next();
            Employee employee = (Employee) hashMap.get(next);
            if(employee != null && employee.getSalary() > 18000.0){
                System.out.println(employee);
            }
        }
        // 增强for循环遍历entrySet
        System.out.println("增强for循环遍历entrySet");
        Set set1 = hashMap.entrySet();
        for(Object entry : set1){
            Map.Entry entry1 = (Map.Entry)entry;
            Employee employee = (Employee) entry1.getValue();
            if(employee != null && employee.getSalary() > 18000.0){
                System.out.println(employee);
            }
        }
        // 迭代器遍历entrySet
        System.out.println("迭代器遍历entrySet");
        Iterator iterator2 = set1.iterator();
        while (iterator2.hasNext()){
            Map.Entry entry = (Map.Entry)iterator2.next();
            Employee employee = (Employee) entry.getValue();
            if(employee != null && employee.getSalary() > 18000.0){
                System.out.println(employee);
            }
        }



    }


}
class Employee{
    private String name;
    private Double salary;
    private int id;

    public Double getSalary() {
        return salary;
    }

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

    public Employee() {
    }

    public Employee(String name, Double salary, int id) {
        this.name = name;
        this.salary = salary;
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return id == employee.id &&
                Objects.equals(name, employee.name) &&
                Objects.equals(salary, employee.salary);
    }

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

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

        

4.Map的实现类

        4.1HashMap

  •                         HashMap是Map接口使用频率最高的实现类
  •                         HashMap是以键值对的形式来存储数据      
  •                         key不能重复,value可以重复,允许使用null键和null值
  •                         如果添加相同的key则会覆盖原来的key-value(相当于key不变,value更新为最新的值)
  •                        与HashSet一样不能保证映射的顺序,因为底层是以hash表的方式来存储的
  •                        HashMap没有实现线程同步,因此线程不安全

                4.1.1HashMap底层实现原理简述

                        1.当往HashMap集合中添加第一个元素时,调用key的hashcode方法计算出hash值,然后通过某种算法得出在table数组的索引位置

                        2.如果该位置没有元素,则直接添加

                        3.如果该位置有元素则调用key的equals方法,如果返回true,则覆盖掉相同key的value。如果返回false,则将要添加的元素链接在该元素的的后面

                4.1.2 HashMap底层扩容机制(无参构造器并且针对的是jdk1.8)

                        1.先初始化一个空的table,当往该table中添加第一个元素时,该数组扩容为16,加载因子为0.75,临界值为12

                        2.当table中的元素个数超过12时,以2倍当前容量进行扩容,即扩为32,加载因子为0.75,临界值为24(后续添加元素以此类推,注意table数组不会无限扩容,有一个上限)

                        3.当table数组大小>=64且链表大小>=8时,该链表会转化成红黑树

                4.1.3 HashMap实现类之LinkedHashMap

                        LinkedHashMap相较于HashMap在查询方面效率更高,因为其底层实现了双向链表。

       4.2TreeMap

                TreeMap在使用过程中需要用到自然排序和定制排序,在用到自然排序时,key所在的类要实现comparatable接口,在使用定制排序时,TreeMap构造器中要传入匿名内部类对象

                4.2.1自然排序

TreeMap treeMap1 = new TreeMap();
        treeMap1.put(new Employee(1,"jack"),1);
        treeMap1.put(new Employee(1,"lucy"),2);
        treeMap1.put(new Employee(5,"jerry"),3);
        System.out.println(treeMap1);
class Employee implements Comparable{
    private int age;
    private String name;

    public Employee() {
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

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


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

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

    @Override
    public int compareTo(Object o) {
        if(o instanceof Employee){
            Employee employee = (Employee)o;
            // 按照年龄来排序
            int compare = Integer.compare(this.age, employee.age);
            // 如果年龄相同,按照姓名来排序
            if(compare == 0){
                return this.name.compareTo(employee.name);
            }
            return compare;

        }
        return 0;
    }
}

                4.2.2 定制排序

TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        treeMap.put("no1","黄劭鸿");
        treeMap.put("no2","黄劭鸿");
        treeMap.put("no3","黄劭鸿");
        treeMap.put("no4","黄劭鸿");
        treeMap.put("no5","黄劭鸿");
        treeMap.put("no6","黄劭鸿");
        treeMap.put("no7","黄劭鸿");

                 注意:无论是定制排序还是自然排序,当比较结果返回零时,该元素不会加入到TreeMap集合中,理由如下:

java 最简单定义map java定义一个map集合_开发语言_14

                        

        4.3Hashtable

                        1.Hashtable的键值都不能为null,如果为null则会报空指针异常

                        2.Hashtable是线程安全的

               4.3.1 Hashtable底层实现原理简述 

                        1.当往Hashtable集合中添加第一个元素时,调用key的hashcode方法计算出hash值,然后通过某种算法得出在table数组的索引位置

                        2.如果该位置没有元素,则直接添加

                        3.如果该位置有元素则调用key的equals方法,如果返回true,则覆盖掉相同key的value。如果返回false,则将要添加的元素链接在该元素的的后面(注意Hashtanle的数据结构为数组+链表),链表不会转化成红黑树

                4.3.2 Hashtable底层扩容机制

                        1.table数组初始为空,当往Hashtable集合中添加第一个元素时,table数组扩容为11,加载因子为0.75,临界值为8

                        2.当table数组中的个数超过8的时候,以2倍原数组+1的原则扩容,即扩为23,加载因子为0.75,临界值为17(后面的扩容以此类推,同样table数组不能无限扩容)

                4.3.3 Hashtable实现类之Properties

                        Properties与配置文件相关,可以给它的对象发送消息,来读取配置文件中的相关内容。

package com.atguigu.java;

import org.junit.Test;

import java.io.FileInputStream;
import java.util.Properties;

public class PropertiesTest {
    @Test
    public void testProperties() throws Exception{

        Properties properties = new Properties();
        FileInputStream fileInputStream = new FileInputStream("jdbc.properties");
        properties.load(fileInputStream);
        String name = properties.getProperty("name");
        String password = properties.getProperty("password");

        System.out.println("name:"+name+",password:"+password);


    }
}