12.Map集合

目录

12.Map集合

12.1.Map与Collection接口下的集合区别

12.2.Map接口特点

12.3.Map接口常用方法

12.4.遍历map三种方式

12.4.1.Map集合第一种遍历方式:键找值的方式

12.4.2.Map集合第二种遍历方式:使用Entry对象来遍历

12.4.3.Map集合第三种遍历方式:JDK8新特性新增的lambda表达式遍历Map的方法——Map.forEach();

12.5.Map接口实现类_HashMap

12.5.1.HashMap存储结构和特点

12.5.1.HashMap存储自定义类型键值

12.5.2.Map集合如何保证key唯一(不重复)

12.6.Map实现类_LinkedHashMap特点

12.7.HashMap与Hashtable区别

12.8.练习:字符串中每一个字符出现的次数


12.Map集合

  • 能够说出Map集合特点
  • 使用Map集合添加方法保存数据

  • 使用“键值对”方式遍历Map集合

  • 使用HashMap存储自定义键值对的数据

  • 能够使用HashMap编写斗地主洗牌发牌案例

12.1.Map与Collection接口下的集合区别

1.Map集合也是一个工具,在java.util包中,它是一个接口,有两个泛型Map<K,V>,K表示键,V表示值。键唯一。
2.通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同
   1.Collection<E>接口定义了单列集合规范,该接口中的集合每次存储一个元素。单身接口。
   2.Map<K,V>接口定义了双列集合的规范,该接口下的集合每个元素都有键与值两个部分组成。
   3.Collection中的集合称为单列集合,Map中的集合称为双列集合。

12.2.Map接口特点

  1.java.util.Map<k,v>集合
  2:Map集合的特点:
      1.Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
      2.Map集合中的元素,key和value的数据类型可以相同,也可以不同
      3.Map集合中的元素,key是不允许重复的(key唯一),value可以
      4.Map集合中的元素,key和value是一一对应的。
  

12.3.Map接口常用方法

 * Map接口中常用方法:
 * public V put(K key,V value):把指定的键与值添加到Map集合中
 * public V remove(Object key):把指定的键所对应的键值对元素在Map集合中删除
 * public V get(Object key):根据指定的键,在Map集合中获取对应的值
 * boolean containsKey(Object key):判断集合中是否包含指定的键

 
     * 1.public V put(K key,V value):把指定的键与值添加到map集合
     *   返回值:v
     *        存储键值对的时候,key不重复,返回值v是null
     *        存储键值对的时候,key重复,会使用新的value替换map中重复的value,
     *                         返回被替代的value值。

 

     *2.public V remove(Object key):把指定的键所对应的键值对元素在Map集合中删除,
     *                             返回被删除元素的值。
     * 返回值:v
     *       key存在,返回值v为被删除的值。
     *       key不存在,返回值v为null。
 
     

     * 3.public V get(Object key):根据指定的键,在Map集合中获取对应的值
     *   返回值:key存在,返回对应的value值
     *          key不存在,返回null

    

     * 4.boolean containsKey(Object key):判断集合中是否包含指定的键
     *   包含返回true,否则false
  
public class Demo2_map {
    public static void main(String[] args) {
        // show01();
        // show02();
        //show03();
        show04();
    }

  
     //1.public V put(K key,V value):把指定的键与值添加到map集合

     private static void show01(){
         //创建Map集合对象,使用多态方式(接口来接收子类对象)
         Map<String,String> map=new HashMap<>();

         String v1 = map.put("李晨", "范冰冰1");
         System.out.println("v1:"+v1);//v1:null

         String v2 = map.put("李晨", "范冰冰2");
         System.out.println("v2:"+v2);//v2:范冰冰1(键重复,返回被替代的值)

         System.out.println(map);//{李晨=范冰冰2}

         map.put("冷锋","龙小云");
         map.put("杨过","小龙女");
         map.put("伊志平","小龙女");
         System.out.println(map);
        // {杨过=小龙女, 伊志平=小龙女, 李晨=范冰冰2, 冷锋=龙小云}
     }



    //2.public V remove(Object key):把指定的键所对应的键值对元素在Map集合中删除,
    
    private static void show02(){
        //创建Map集合对象,多态方式
        Map<String,Integer>map1=new HashMap<>();
        map1.put("赵丽颖",168);
        map1.put("杨颖",165);
        map1.put("林志颖",178);
        System.out.println(map1);//{赵丽颖=168, 杨颖=165, 林志颖=178}

        Integer v1 = map1.remove("林志颖");
        System.out.println("v1:"+v1);//v1:178
        System.out.println(map1);//{赵丽颖=168, 杨颖=165}

        Integer v2 = map1.remove("林志玲");
        System.out.println("v2:"+v2);//v2:null表示集合中没有该键值对
    }


   
     //3.public V get(Object key):根据指定的键,在Map集合中获取对应的值
   
     private static void show03(){
         //创建map集合对象
         Map<String,Integer>map2=new HashMap<>();
         map2.put("赵丽颖",168);
         map2.put("杨颖",165);
         map2.put("林志颖",178);
         Integer v3 = map2.get("杨颖");
         System.out.println("v3:"+v3);//v3:165
         Integer v4 = map2.get("迪丽热巴");
         System.out.println("v4:"+v4);//v4:null
     }


    
     //4.boolean containsKey(Object key):判断集合中是否包含指定的键
  
     private static void show04(){
         //创建map集合对象
         Map<String,Integer>map3=new HashMap<>();
         map3.put("赵丽颖",168);
         map3.put("杨颖",165);
         map3.put("林志颖",178);
         boolean b1 = map3.containsKey("赵丽颖");
         System.out.println("b1:"+b1);//b1:true
         boolean b2 = map3.containsKey("赵颖");
         System.out.println("b2:"+b2);//b2:false
     }
}

12.4.遍历map三种方式

12.4.1.Map集合第一种遍历方式:键找值的方式

 1.public Set<K> keySet():获取Map集合中所有的键,存储到Set集合中。
 2.Map集合第一种遍历方式:键找值的方式
      1.由map集合中的keySet()方法获取Map集合中所有的键,存储到Set集合中
      2.使用迭代器或增强for遍历Set集合,获取map集合中每一个key
      3.再由map集合中get(key)方法获取map集合中每一个key对应的value.

public class Demo3_map {
    public static void main(String[] args) {
        //创建Map集合对象,多态方式
        Map<String,Integer>map=new HashMap<>();
        map.put("赵丽颖",168);
        map.put("杨颖",165);
        map.put("林志颖",178);
        //1.由map集合中的keySet()方法获取Map集合中所有的键,存储到Set集合中
        Set<String> set = map.keySet();
        //2.使用迭代器或增强for遍历Set集合,获取map集合中每一个key
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            String key = it.next();
            //3.再由map集合中get(key)方法获取map集合中每一个key对应的value.
            Integer value = map.get(key);
            System.out.println(key+"="+value);
        }
        System.out.println("............. ....");
        //或者使用增强for来遍历Set集合
        for (String key : set) {//简化for(String key:map.keySet())
            //3.再由map集合中get(key)方法获取map集合中每一个key对应的value.
            Integer value = map.get(key);
            System.out.println(key+"="+value);
        }
    }
}

 

12.4.2.Map集合第二种遍历方式:使用Entry对象来遍历

  • 在 Map.Entry 接口中以下的方法最为常用:

 1.public Set<Map.Entry<K,V>> entrySet():获取Map集合中所有键值对对象的集合(Set集合)
 2.Map.Entry<K,V>:Map接口中的一个内部接口Entry
 3.作用:当Map集合创建时,会在Map集合中创建一个Entry对象,用于封装Map集合中的一组键值(也叫键值对对象)
 4.Map集合第二种遍历方式:使用Entry对象来遍历
     1.由map集合中的Set<Map.Entry<K,V>> entrySet()方法,把map集合中多个Entry对象取出来存储到Set集合中。
     2.遍历Set集合,获取Set集合中每一个Entry对象
     3.由Entry对象中的方法getKey()和getValue()分别获取键与值

public class Demo4_map {
    public static void main(String[] args) {

        //创建Map集合对象,多态方式
        Map<String,Integer>map=new HashMap<>();
        map.put("赵丽颖",168);
        map.put("杨颖",165);
        map.put("林志颖",178);

        /*1.由map集合中的Set<Map.Entry<K,V>> entrySet()方法,
          把map集合中多个Entry对象取出来存储到Set集合中。
        */

        Set<Map.Entry<String,Integer>> set=map.entrySet();//创建set集合并接收对象

        /*2.遍历Set集合,获取Set集合中每一个Entry对象*/
        //2.1使用迭代器遍历set集合
        Iterator<Map.Entry<String, Integer>> it = set.iterator();//创建迭代器
        while(it.hasNext()){
            Map.Entry<String, Integer> entry = it.next();//获取集合中entry对象
            //3.由Entry对象中的方法getKey()和getValue()分别获取键与值
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"="+value);
        }
        System.out.println("........................");

        //2.2使用增强for遍历set集合
        for (Map.Entry<String, Integer> entry : set) {
            //3.由Entry对象中的方法getKey()和getValue()分别获取键与值
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"="+value);
        }
    }
}

12.4.3.Map集合第三种遍历方式:JDK8新特性新增的lambda表达式遍历Map的方法——Map.forEach();

ublic static void main(String[] args) {
		Map<String,String> map = new HashMap<>();
		map.put("1","飞机");
		map.put("2","坦克");
		map.put("3","大炮");
		map.forEach((k,v)-> {
		    System.out.println(k+":"+v);
		});
	}

12.5.Map接口实现类_HashMap

12.5.1.HashMap存储结构和特点

  • java.util.HashMap<K,V>集合 implements Map<K,V>接口
  • HashMap集合底层是哈希表:查询速度特别快。
  • jdk1.8之前,哈希表结构:数组+单向链表;jdk1.8之后,哈希表结构:数组+单向链表/红黑树(链表长度超过8)
  • HashMap集合是一个无序的集合,key唯一(不重复)

12.5.1.HashMap存储自定义类型键值

12.5.2.Map集合如何保证key唯一(不重复)

  • 若键key是自定义类型,那么该类型的类必须重写hashCode和equals方法,以保证唯一性(不重复)
  • 下面键key是String类型,不需要重写。
public class Demo5_Person {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

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

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


/**
 * HashMap存储自定义类型键值
 * Map集合保证key是唯一的方法:作为key的元素,必须重写hashCode方法和equals方法
 *
 * 下面案例是演示键为String类型,已经默认重写了hashCode和equals方法,不需再重写。
 * 值为Demo5_Person类型,属于自定义类型。不需要重写。
 */
public class Demo5_map {
    public static void main(String[] args) {
        show01();
    }

    /**
     * HashMap存储自定义类型键值
     * key:String类型
     *     String类已经重写了hashCode和equals方法,因此可以保证key唯一。
     * value:Demo5_Person类型(自定义)
     *     value可以重复(即同名同年龄的人视为同一人)
     */
    private static void show01(){
        //创建HashMap集合,键值对中值类型是自定义的Person类型
        HashMap<String,Demo5_Person> map = new HashMap<>();
        //往集合添加元素
        map.put("北京",new Demo5_Person("张三",18));
        map.put("上海",new Demo5_Person("李四",19));
        map.put("广州",new Demo5_Person("王五",20));
        map.put("北京",new Demo5_Person("赵六",18));
        //使用keySet和增强for遍历map集合
        Set<String> set = map.keySet();//将map中所有key存入set集合
        for (String key : set) {
            Demo5_Person person = map.get(key);
            System.out.println(key+":"+person);
        }
        /*上海:Person{name='李四', age=19}
          广州:Person{name='王五', age=20}
          北京:Person{name='赵六', age=18}
        */
        //因为键key是String类型,该String类又默认重写了hashCode和equals方法,
        //因此上述存储的元素实现了key值唯一。
    }
}

  • 下面键key是自定义类型,需重写hashCode和equals方法

 * HashMap存储自定义类型键值
 *   Map集合保证key是唯一的方法:作为key的元素,必须重写hashCode方法和equals方法
 *  
 *   下面案例是演示键为Person类型,需要在Person类中重写hashCode方法和equals方法。
 *   值为String类型,不需重写。(只要求key唯一)

public class Demo6_Person {
    private String name;
    private int age;

    public Demo6_Person(String name, int age) {
        this.name = name;
        this.age = 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 String toString() {
        return "Demo6_Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }
}


 * HashMap存储自定义类型键值
 * Map集合保证key是唯一的方法:作为key的元素,必须重写hashCode方法和equals方法
 *
 * 下面案例是演示键为Person类型,需要在Person类中重写hashCode方法和equals方法。
 *             值为String类型,不需重写。(只要求key唯一)


public class Demo6_map {
    public static void main(String[] args) {
       show01();
    }

    /**
     * HashMap存储自定义类型键值:
     * key:Person类型,Person类需要重写hashCode方法和equals方法,以保证key唯一。
     * value:String类型,value可以重复
     */
    private static void show01(){
        //创建HashMap集合(键为自定义Person类型,值为String)
        HashMap<Demo6_Person,String > map = new HashMap<>();
        //往集合中添加元素
        map.put(new Demo6_Person("彩鳞",18),"美杜莎");
        map.put(new Demo6_Person("熏儿",19),"古族");
        map.put(new Demo6_Person("云韵",20),"花宗");
        map.put(new Demo6_Person("小医仙",18),"厄难毒体");
        map.put(new Demo6_Person("彩鳞",18),"七彩吞天莽");
        //使用EntrySet和增强for遍历map集合
        //1.调用map中的EntrySet方法获取map中的Entry对象存于Set集合
        Set<Map.Entry<Demo6_Person,String>>set=map.entrySet();
        //2.遍历Set集合中Entry对象
        for (Map.Entry<Demo6_Person, String> entry : set) {
            //3.Entry对象中的getKey和getValue方法获取Entry对象中的键值
            Demo6_Person key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+":"+value);
        }
    }
}

12.6.Map实现类_LinkedHashMap特点

  • java.util.LinkedHashMap<k,v> extends HashMap<K,V>
  • Map接口的哈希表和链表列表实现,具有可预知的的迭代顺序(有序),key唯一不重复
  • 底层结构:哈希表+链表(记录元素的顺序);
public class Demo7_LinkedHashMap {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("a","a");
        map.put("b","b");
        map.put("c","c");
        map.put("a","d");
        System.out.println(map);//{a=d, b=b, c=c}key不允许重复,且无序。

        LinkedHashMap<String, String> link = new LinkedHashMap<>();
        link.put("a","a");
        link.put("b","b");
        link.put("c","c");
        link.put("a","d");//{a=d, b=b, c=c}key不重复,有序
    }
}

12.7.HashMap与Hashtable区别

* 1.java.util.Hashtable<K,V>集合 implements Map<K,V>

 * 2.HashMap与Hashtable的区别:

  • Hashtable:底层也是一个哈希表,是一个线程安全(单线程)的集合,因此速度慢。
  • HashMap:   底层是一个哈希表(数组+链表/红黑树),是一个线程不安全(多线程)的集合,因此速度快。

 

  • HashMap集合(包括之前学的所有集合):都可以存储null键,null值
  • hashtable集合,不能存储null键,null值

 

  •  Hashtable和vector集合一样,在jdk1.2版本之后被更先进集合(HashMap,ArrayList)取代
  • Hashtable的子类Properties依然在使用,这个集合是一个唯一和IO流结合的集合
public class Demo8_Hashtable {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put(null,"a");
        map.put("b",null);
        map.put(null,null);

        Hashtable<String , String> table = new Hashtable<>();
        table.put(null,"a");//NullPointerException空指针异常
        table.put("b",null);//NullPointerException
        table.put(null,null);//NullPointerException
        //Hashtable集合中的键与值都不允许出现null
    }
}

12.8.练习:字符串中每一个字符出现的次数

* 练习:计算一个字符串中每一个字符出现的次数
 * 思路:
 *     1:使用Scanner获取用户输入的一个字符串
 *     2:下面使用HashMap<Character,Integer>集合以键值对记录每个字符及对应的数量
 *     3:首先需要遍历字符串,获取每一个字符,由两种方式:
 *       i.String类的toCharArray方法,把字符串转换为数组,遍历数组即可。
 *       ii.String类的length方法加上charAt(索引)来获取每一个字符。
 *     4:使用Map集合中方法判断获取到的字符串(key)是否存储在Map集合中
 *        i.使用Map集合中containsKey(获取的字符串)方法,返回布尔值
 *            true:字符存在
 *                    则通过字符(key),获取value(统计个数),
 *                    把value++,
 *                    把新的value存储到Map集合
 *            false:字符不存在
 *                    则把字符作为key,把1作为value存储到Map集合
 *        ii.或也可以使用Map集合中get(key)方法
 *           返回null,表示key不存在,把对应键值对加入集合
 *           返回不是null,则找到key对应的value自增后再存入集合。


public class Demo9_lianxi {
    public static void main(String[] args) {
        //1.使用Scanner获取用户输入的字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();
        //2.创建Map集合,key是字符串的字符,value是字符个数
        HashMap<Character, Integer> map = new HashMap<>();
        //3.遍历字符串,获取每一个字符
        for (char c:str.toCharArray()){
            //4.使用获取到的字符,去Map集合判断key是否存在
            if (map.containsKey(c)){
                //key存在
                Integer value = map.get(c);
                value++;
                map.put(c,value);//覆盖之前的键值对
            }else{
                //key不存在
                map.put(c,1);
            }
        }
        /*for (Character key : map.keySet()) {
            Integer value = map.get(key);
            System.out.println(key+":"+value);
        }*/
        System.out.println(map);
        /*输入asdfgasdfghj
        * 输出{a=2, s=2, d=2, f=2, g=2, h=1, j=1}
        * */
    }
}

 

package demo21;

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

/**
 * Map
 * HashMap/Hashtable/ConcurrentHashMap
 * TreeMap
 * LinkedHashMap
 * 以上集合都适合下面操作
 */
public class HashMapMain {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("k1","你");
        map.put("k2","好");
        map.put("k3","啊");
        map.put("k4","你");
        String v = map.get("k1");
        System.out.println(v);
        System.out.println("======================");
        Set<String> set = map.keySet();
        for (String s:set) {
            System.out.println(s+"->"+map.get(s));
        }
        System.out.println("======================");
        Collection<String> values = map.values();
        for (String s:values) {
            System.out.print(s+" ");
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值