Tips:样式蚂蚁森林浇水get

java进阶——day04-1 Map

Map集合

概述

  Collection中的集合:元素是孤立存在的(理解为单身),向集合存储元素采用一个个元素的存储方式

  Map中的集合:元素是成对存在的(理解为夫妻),每个元素由两部分组成,通过键能找到对应的值

  Collection中的集合称为单列集合

  Map中的集合称为双列集合

  注意:

  Map集合不能包含重复的键(key唯一),但是值(value不唯一)可以重复;每个键只能对应一个值。

Map常用子类---HashMap

  1.HashMap集合底层是哈希表,查询速度特别快

  JDK1.8前:数组+单向链表

  JDK1.8后:数组+单向链表/红黑树(链表长度>8采用红黑树,提高查询速度)

  2.HashMap集合是一个无序集合,存储和取出元素的顺序可能不一致

  2、LinkedHashMap

  1.LinkedHashMap集合底层是哈希表+链表(包证迭代的顺序)

  2.LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的

  3、注意

  HashMap&LinkedHashMap:由于要保证键的唯一性,需要重写hashCode()方法和equals()方法

  Map接口中的集合都有两个泛型变量,在使用时,要为两个泛型变量赋予数据类型。两个变量的数据类型可以相同也可以不同。

 Map接口中的常用方法

  public V put(K key, V value) : 把指定的键与指定的值添加Map集合中。

package day04;

import java.util.HashMap;

public class Map_method {
    public static void main(String[] args) {
        //创建Map对象——hashMap
        //此处 两个泛型变量都为String类型
        HashMap<String,String> map = new HashMap<>();
        //往Map中添加键值对
        map.put("陈易安","曾勇");
        map.put("胡一菲","曾小贤");
        map.put("关谷神奇","唐悠悠");
        System.out.println(map);//{陈易安=曾勇, 胡一菲=曾小贤, 关谷神奇=唐悠悠}
    }
}
.put(key,value);

  public V remove(Object key) : 把指定的键(key)所对应的键值(vlaue)元素Map集合中删除返回被删除元素的值

package day04;

import java.util.HashMap;

public class Map_method {
    public static void main(String[] args) {
        //创建Map对象——hashMap
        //此处 两个泛型变量都为String类型
        HashMap<String,String> map = new HashMap<>();
        //往Map中添加键值对
        map.put("陈易安","曾勇");
        map.put("胡一菲","曾小贤");
        map.put("关谷神奇","唐悠悠");
        System.out.println(map);//{陈易安=曾勇, 胡一菲=曾小贤, 关谷神奇=唐悠悠}
        String re = map.remove("关谷神奇");
        System.out.println(re);//唐悠悠
        System.out.println(map);//{陈易安=曾勇, 胡一菲=曾小贤}

    }
}
.remove(key);

  public V get(Object key): 根据指定的键(Key),在Map集合中获取对应的值(Value)。 

package day04;

import java.util.HashMap;

public class Map_method {
    public static void main(String[] args) {
        //创建Map对象——hashMap
        //此处 两个泛型变量都为String类型
        HashMap<String,String> map = new HashMap<>();
        //往Map中添加键值对
        map.put("陈易安","曾勇");
        map.put("胡一菲","曾小贤");
        map.put("关谷神奇","唐悠悠");
        System.out.println(map);//{陈易安=曾勇, 胡一菲=曾小贤, 关谷神奇=唐悠悠}
        String user = map.get("陈易安");
        System.out.println(user);//曾勇
    }
}
.get(key)

  public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中 

package day04;

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

public class Map_method {
    public static void main(String[] args) {
        //创建Map对象——hashMap
        //此处 两个泛型变量都为String类型
        HashMap<String,String> map = new HashMap<>();
        //往Map中添加键值对
        map.put("陈易安","曾勇");
        map.put("胡一菲","曾小贤");
        map.put("关谷神奇","唐悠悠");
        System.out.println(map);//{陈易安=曾勇, 胡一菲=曾小贤, 关谷神奇=唐悠悠}
        //定义String类 来接收key 因为key也是String类型
        Set<String> strings = map.keySet();
        for (String s:strings
             ) {
            System.out.print(s+" ");//陈易安 胡一菲 关谷神奇 
        }

    }
}
.setKey();

  public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的 键值对对象 的集合(Set集合)

  作用解析:当Map集合一创建,就会在Map集合中创建一个Entry对象,用来记录键与值---->证明(结婚证)

 

package day04;

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

public class Map_method {
    public static void main(String[] args) {
        //创建Map对象——hashMap
        //此处 两个泛型变量都为String类型
        HashMap<String,String> map = new HashMap<>();
        //往Map中添加键值对
        map.put("陈易安","曾勇");
        map.put("胡一菲","曾小贤");
        map.put("关谷神奇","唐悠悠");
        System.out.println(map);//{陈易安=曾勇, 胡一菲=曾小贤, 关谷神奇=唐悠悠}
        Set<Map.Entry<String, String>> entries = map.entrySet();
        System.out.println(entries);//[陈易安=曾勇, 胡一菲=曾小贤, 关谷神奇=唐悠悠]

    }
}
.entrySet()

 

 

 

 Map集合遍历Key找Vlaue的方法

 

 

  Map中存放的是两种对象,分别为键(Key)与 值(Value)他们是一一对应的关系。而在Map集合创建时,会由Entry记录,所以我们可以通过Entry提供的获取键和值的方法来遍历

  获取Entry对象的键:

  public K getKey()

 

   获取Entry对象的值:

  public V getValue();

  在Map集合中也提供了获取所有Entry对象的方法

  public Set<Map.Entry<K,V>> entrySet():获取Map集合中所有键值对对象的集合(Set集合)

  例如:

package day04;

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

public class Map_Entry {
    public static void main(String[] args) {
        //创建hashMap对象
        Map<Integer,String> Student = new HashMap<>();
        //添加元素到hashMap对象中
        Student.put(1,"刘昊然");
        Student.put(2,"张子枫");
        Student.put(3,"欧阳娜娜");
        //利用Map 的 SetEntry获取所有键值对对象(SetEntry获得的集合是Set集合)
        Set<Map.Entry<Integer, String>> st = Student.entrySet();
        //我们利用Set集合的迭代器遍历键值对对象
        Iterator<Map.Entry<Integer, String>> it = st.iterator();
        while (it.hasNext()){
            //创建Entry对象 接收Entry对象
            Map.Entry<Integer,String> getEKV = it.next();
            //通过getKey()和getValue() 分别获取键值
            int key = getEKV.getKey();
            String vlaue = getEKV.getValue();
            System.out.println("学号为"+key+"的学生,叫做:"+vlaue);
            /**
             * 学号为1的学生,叫做:刘昊然
             * 学号为2的学生,叫做:张子枫
             * 学号为3的学生,叫做:欧阳娜娜
             */
        }


    }
}
SetEntry

  注意(重点):

  Map集合不能直接使用迭代器或者foreach进行遍历,但是转成Set集合就可以使用了。

package day04;

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

public class Map_method {
    public static void main(String[] args) {
        //创建Map对象——hashMap
        //此处 两个泛型变量都为String类型
        HashMap<String,String> map = new HashMap<>();
        //往Map中添加键值对
        map.put("陈易安","曾勇");
        map.put("胡一菲","曾小贤");
        map.put("关谷神奇","唐悠悠");
        
        //通过Map的SetEntry方法 获取Map中的键值对对象
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        //使用foreach遍历Set集合
        for (Map.Entry<String,String> entry:entrySet
             ) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"的对象是"+value);
            /**
             * 
             */
        }
    }
}
for each遍历

HashMap存储自定义类型键值

练习:

  每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到Map集合。学生作为键,家庭住址作为值。

package day04;

public class Student {
    //成员变量
    private String name;
    private int age;
    //无参构造方法
    public Student() {
    }
    //全参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //get & set
    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;
    }
    //重写toString
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}
Student类
package day04;

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

public class practice {
    public static void main(String[] args) {
        //创建hashMap对象 键:学生 值:家庭住址
        Map<Student,String> stuAddress = new HashMap<>();
        //往集合添加对象 学生 以及 家庭住址
        stuAddress.put((new Student("王俊凯",22)),"重庆");
        stuAddress.put((new Student("易烊千玺",18)),"湖南");
        stuAddress.put((new Student("王源",20)),"中国");
        //通过Map的Entryset方法 获取Map对象中的所有键值对对象
        Set<Map.Entry<Student, String>> Stu = stuAddress.entrySet();
        //通过迭代器遍历
        Iterator<Map.Entry<Student, String>> it = Stu.iterator();
        while (it.hasNext()){
            Map.Entry<Student,String> en = it.next();
            Student s = en.getKey();
            String add = en.getValue();
            System.out.println(s.getAge()+"岁的"+s.getName()+",家住"+add);
            /**
             * 18岁的易烊千玺,家住湖南
             * 22岁的王俊凯,家住重庆
             * 20岁的王源,家住中国
             */
        }
    }
}
main

  //此处输出的对象是无序的

Map常用子类---LinkedHashMap

  我们知道hashMap保证成对的元素唯一,且查询速度非常快(数组+链表/红黑树),但是存取元素是无序的,但是通过LinkedHashMap,我们就可以达到存取元素有序,且同样快速的效果

package day04;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class LinkedHashMap_demo {
    public static void main(String[] args) {
        //创建LinkedHashMap对象
        LinkedHashMap<Integer,String > map = new LinkedHashMap<>();
        //添加元素
        map.put(1,"白展堂");
        map.put(3,"吕秀才");
        map.put(2,"佟湘玉");
        map.put(4,"郭芙蓉");
        System.out.println(map);//{1=白展堂, 3=吕秀才, 2=佟湘玉, 4=郭芙蓉}
        //顺序没有打乱

        //通过entrySet 获取集合中所有键值对对象
        Set<Map.Entry<Integer, String>> en = map.entrySet();
        //迭代器遍历
        Iterator<Map.Entry<Integer, String>> it = en.iterator();
        while (it.hasNext()){
            Map.Entry<Integer,String> p = it.next();
            int num = p.getKey();
            String name = p.getValue();
            System.out.println(num+"===="+name);
            /**
             * 1====白展堂
             * 3====吕秀才
             * 2====佟湘玉
             * 4====郭芙蓉
             */
        }
    }
}
LinkedhashMap

  注意:

  此处的有序,并不是指从小到大的排序,而是元素怎么存的 取出来的顺序就是什么样的

Map集合练习

需求:计算一个字符串中,每个字符出现的次数

分析:

  1、获取一个字符串对象

  2、创建Map集合,键代表字符,值代表次数

  3、遍历字符串得到每个字符。

  4、判断Map中是否有该键

  5、如果没有,第一次出现,存储次数为1;如果有说明已经出现过,获取对应的值进行++,再次存储。

  6、打印结果

package day04;

import java.util.*;

public class practice01 {
    public static void main(String[] args) {
        //获取用户输入的字符串
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入一个字符串:");
        String str = sc.nextLine();
        //调用方法
        findChar(str);
    }
    //定义查找字符方法
    public static void findChar(String line){
        //创建Map集合存储 字符 次数
        HashMap<Character,Integer> map = new HashMap<>();
        //遍历字符串
        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            //判断该字符是否存在map集合的键中
            if(!map.containsKey(c)){//不包含这个键
                map.put(c,1);//第一次添加
            }else {//存在集合中
                //获取之前的次数
                Integer count =map.get(c);
                //再次存入map集合
                map.put(c,++count);
            }
        }
        Set<Map.Entry<Character, Integer>> et = map.entrySet();
        Iterator<Map.Entry<Character, Integer>> it = et.iterator();
        while (it.hasNext()){
            Map.Entry<Character,Integer> ET = it.next();
            Character key = ET.getKey();
            int value = ET.getValue();
            System.out.println(key+" 出现了"+value+"次");
        }
    }
}
practice

模拟斗地主洗牌发牌

规则:

  1、一组54张扑克牌

  2、54张牌顺序打乱

  3、三个玩家参与游戏,三人交替摸牌,每人17张,剩余3张底牌

  4、查看三人各自手中的牌(按照牌的大小顺序)、底牌

需求分析

  1、准备牌:

  完成数字与纸牌的映射关系:

  使用双列集合Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系

  2、洗牌

  Collections.shuffle()

  3、发牌

  将每人以及底牌设计为ArrayList,留三张底牌,剩余通过对3取模依次发牌,存放过程要求数字大小与斗地主规则大小对应

  4、看牌

  通过Map集合找到对应字符展示

package day04;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;

public class pokerMap_pratice {
    public static void main(String[] args) {
        //创建Map集合
        HashMap<Integer,String> pokerMap = new HashMap<>();
        //创建花色
        ArrayList<String> colors = new ArrayList<>();
        ArrayList<String> numbers = new ArrayList<>();
        //通过Collectios.addAll()存储花色 和数字
        Collections.addAll(colors,"♥","♠","♣","♦");
        Collections.addAll(numbers,"2","A","K","Q","J","10","9","8","7","6","5","4","3");
        //设置编号?后期用于排序
        int count = 1;
        pokerMap.put(count++,"大王");
        pokerMap.put(count++,"小鬼");
        //创建牌面 并存储到pokerMap中
        for (String color:colors
             ) {
            for (String num : numbers
                 ) {
                String card = color + num;//牌面
                pokerMap.put(count++,card);
            }
        }
        //洗牌
        //取出编号(Integer)集合 按照编号打乱
        Set<Integer> numSet = pokerMap.keySet();
        //因为要打乱顺序 所以先将编号转到List集合 防止默认排序
        ArrayList<Integer> numList = new ArrayList<>();
        numList.addAll(numSet);

        //打乱
        Collections.shuffle(numList);
        //创建三个玩家 以及底牌
        ArrayList<Integer> Nop1 = new ArrayList<>();
        ArrayList<Integer> NOp2 = new ArrayList<>();
        ArrayList<Integer> NOp3 = new ArrayList<>();
        ArrayList<Integer> NOdp = new ArrayList<>();
        //存储编号
        for (int i = 0; i < numList.size(); i++) {
            //获取编号
            int NO = numList.get(i);
            //留底牌
            if(i>=51){
                NOdp.add(NO);
            }else if(i%3==0){
                Nop1.add(NO);
            }else if(i%3 == 1){
                NOp2.add(NO);
            }else {
                NOp3.add(NO);
            }
        }
        //对编号进行排序
        Collections.sort(Nop1);
        Collections.sort(NOp2);
        Collections.sort(NOp3);
        Collections.sort(NOdp);
        //进行牌面转换
        ArrayList<String> player01 = new ArrayList<>();
        ArrayList<String> player02 = new ArrayList<>();
        ArrayList<String> player03 = new ArrayList<>();
        ArrayList<String> dipai = new ArrayList<>();
        for (Integer i: Nop1
             ) {
            String card = pokerMap.get(i);
            player01.add(card);
        }
        for (Integer i:NOp2
             ) {
            String card = pokerMap.get(i);
            player02.add(card);
        }
        for (Integer i:NOp3
             ) {
            String card = pokerMap.get(i);
            player03.add(card);
        }
        for (Integer i: NOdp
             ) {
            String card = pokerMap.get(i);
            dipai.add(card);
        }
        //查看
        System.out.println("雪影"+player01);
        System.out.println("萌王"+player02);
        System.out.println("雪精灵"+player03);
        System.out.println("底牌"+dipai);
    }
}
Map_List综合应用

主要是通过编号来排序的,例如大王是1 小王2....

--->先将编号存在一个数组中

--->将编号顺序打乱Collections.shuffle()

--->创建玩家集合

--->将打乱的编号存储到玩家集合中

--->将通过遍历玩家集合中的编号 通过get方式 转为牌面

 

posted @ 2021-03-19 22:24  心岛未晴  阅读(84)  评论(0)    收藏  举报