Map
一.Map的概述
	  1.什么是Map集合
		    Collection称为单列集合,元素的孤立存在的
		    Map称为双列集合
		    注意:Collection是单集合的根接口
			         Map是双列集合的根接口
	  2.Map集合的特点
		    a.Collection元素是孤立的,Map的成对的
		    b.Map集合的键不能重复(唯一的),值是可以重复的,通过键能找到一个值。
二.Map集合中常用子类
	  1.HashMap集合介绍
		    底层是哈希表结构
		    无序的
	  2.LinkedHashMap集合的介绍
		    底层是链表+哈希表结构
		    有序的
	  3.Map接口中通用的方法
		    增:public put(K 键,V 值);向Map集合中添加一个键值对。返回被覆盖的键值对的值
		    删:public remove(K 键);根据键,删除集合中键值对。返回被删除的键值对的值
		    改:无
		    查:public get(K 键值);根据键 获取集合中的对应值
		    其他:
			      public boolean containsKey(K key);//判断集合中是否包含指定的键
			      public int size();//返回Map中键值对的个数
		    代码:
 public static void main(String[] args) {
      //1.使用Map集合 进行增删改查
      //实现类:HashMap(无序) LinkHashMap(有序)
      Map<String,Integer> map=new HashMap<String, Integer>();
      //2.添加键值对
        map.put("小米6p",1988);
        map.put("vivo",18784);
        map.put("oppo",1525);
        map.put("苹果",8542);
      //3.删除
        map.remove("vivo");
      //4.修改
        map.put("oppo",2000);
        System.out.println(map);
      //5.个数
        int size = map.size();
        System.out.println(size);
      //6.判断包不包含这个键
        boolean vivo = map.containsKey("vivo");
        System.out.println(vivo);
        }
   4.Map的遍历方式一:以键找值的方式
		    注意:Map集合 第一没有下标 第二也没有继承Collection所以没有迭代器
		    代码:	
 public static void main(String[] args) {
      Map<String,Integer> map=new HashMap<String, Integer>();
      map.put("小米6p",1988);
      map.put("vivo",18784);
      map.put("oppo",1525);
      map.put("苹果",8542);
      //遍历:以键找值
      Set<String> keySet= map.keySet();
      //使用迭代器
      Iterator<String> iterator = keySet.iterator();
      //标准遍历
      while (iterator.hasNext()){
      String key = iterator.next();
      Integer value = map.get(key);
      System.out.println(key+"="+value);
        }
      }
5.Map的遍历方式二:键值对(Entry)方式
     代码: 
public static void main(String[] args) {
      Map<String,Integer> map=new HashMap<String, Integer>();
      map.put("小米6p",1988);
      map.put("vivo",18784);
      map.put("oppo",1525);
      map.put("苹果",8542);
      //遍历:以键找值
      Set<String> keySet= map.keySet();
      //使用迭代器
      Iterator<String> iterator = keySet.iterator();
      //标准遍历
      while (iterator.hasNext()){
      String key = iterator.next();
      Integer value = map.get(key);
      System.out.println(key+"="+value);
        }
      }
   6.练习1:使用HashMap保存自定义对象
		    Student类:
     public class Student {
      private String name;
      private int age;
      public Student(String name, int age) {
      this.name = name;
      this.age = age;
      }
      public Student() {
      }
      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 "Student{" +
      "name='" + name + '\'' +
      ", age=" + age +
      '}';
      }
      @Override
      public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof Student)) return false;
      Student student = (Student) o;
      return age == student.age &&
      Objects.equals(name, student.name);
      }
      @Override
      public int hashCode() {
      return Objects.hash(name, age);
      }
      }
    实现类:
      public static void main(String[] args) {
      Map<Student,String> map=new HashMap<Student, String>();
      //2.添加数据
      map.put(new Student("小草",5),"北京");
    map.put(new Student("小花",1),"北京");
    map.put(new Student("小树",4),"上海");
    map.put(new Student("小苗",8),"深圳");
    map.put(new Student("小虾",66),"西安");
    System.out.println(map);
    map.put(new Student("小草",5),"北京");
    System.out.println(map);
    }
   7.练习2:使用LinkedHashMap保存自定义对象
	    实现类:
/练习,每位学生(姓名,年龄)都有自己的家庭住址,学生作为键,家庭住址为值
//1.定义Map集合
Map<Student,String> map=new LinkedHashMap<Student, String>();
//2.添加数据
map.put(new Student("小草",5),"北京");
map.put(new Student("小花",5),"北京");
map.put(new Student("小树",5),"上海");
map.put(new Student("小苗",5),"深圳");
map.put(new Student("小虾",5),"西安");
//1.第一种遍历方法
Set<Student> students = map.keySet();
Iterator<Student> iterator = students.iterator();
while (iterator.hasNext()){
Student next = iterator.next();
String s = map.get(next);
System.out.println(s+","+next);
}
System.out.println("==================");
//2.第二种遍历方法
Set<Map.Entry<Student, String>> entries = map.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
    注意:
	      使用hashSet或者LinkedMap保证自定义的键时,由于我们保证键的唯一性
	      必须重写自定义类中的HahCode和equals
	  8.Map集合综合练习
		    需求:
			      计算一个字符串中每种字符出现次数
		    思考:
			      以上这种题目,必须使用Map<Character ,Integer>
		    步骤
			      a.定义Map集合,保存字符和对应的次数
			      b.遍历字符串,取出每一个字符
			      c.如果该字符在Map中已经出现了,那么需要把出现次数增加一
				        如果该字符在Map中没有出现,那么需要添加集合中添加该字符,并且为1
			      d.打印Map集合
		    代码:
public static void main(String[] args) {
//控制台输入字符串
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
String next = scanner.next();
//定义Map集合,保存字符和对应的次数
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
//遍历字符串,取出每一个字符
for (int i = 0; i < next.length(); i++) {
char c = next.charAt(i);
if (hashMap.containsKey(c)){
hashMap.put(c,hashMap.get(c)+1);
}else {
hashMap.put(c,1);
}
}
System.out.println(hashMap);
}
三.补充知识点
	  1.JDK快速创建集合的方法
		      List<Integer> nums=List.of(10,20,30,40,50);
		      Set<String> set=Set.of("a","b","c","d");
		      Map<String,Integer> map=Map.of("张三",18,"李四",19,"王五",20);
	  2.快速创建集合的注意事项
		      使用以上三种方式创建的集合,得到的集合都是不可变的集合
		      对不可变集合进行添加,删除,修改,都会抛出UnsupportedOperationException
	  3.Debug模式追踪
		
    F8:代码向下执行一行
		    F7:进入某个方法
		    Ctrl+F2:立即停止程序
		    F9:运行到下一个断点处,如果没有下一个断点,运行完毕整个程序
四.模拟斗地主案例
  核心:为每一张牌,设置一个编号,要求牌越大 编号越大
	  步骤分析:
		    1.需要准备编号和牌对应的Map<Integer,String>集合
		    2.准备一副牌(54个编号)
		    3.洗牌(编号集合)
		    4.发牌(编号)
		    5.排序(编号)
		    6.转牌(把编号转成对应的牌)
		    7.看牌
	  代码实现:
    public static void main(String[] args) {
//        1.需要准备编号和牌对应的Map<Integer,String>集合
        ArrayList<Integer> cardsBox = new ArrayList<Integer>();
        LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
        String[] colars = {"♠", "♥", "♣", "♦"};
        String[] Licensing = {"3", "4", "5", "6", "7", "8", "9", "10", "j", "Q", "K", "A", "2"};
//产生编号和牌
        int id = 1;
        //注意:这里必须外层先遍历 数字,内遍历花色
        for (String s : Licensing) {
            for (String colar : colars) {
                //连接牌
                String s1 = colar + s;
                //保存到map中
                map.put(id, s1);
                //同时添加牌
                cardsBox.add(id);
                id++;
            }
        }
        map.put(id, "小s");
        cardsBox.add(id);
        id++;
        map.put(id, "大s");
        cardsBox.add(id);
        //准备一副牌(54个编号)
        System.out.println(cardsBox);
//        3.洗牌(编号集合)
        Collections.shuffle(cardsBox);
//       3.发牌(剩余3张,作为底牌)
        ArrayList<Integer> p1 = new ArrayList<Integer>();
        ArrayList<Integer> p2 = new ArrayList<Integer>();
        ArrayList<Integer> p3 = new ArrayList<Integer>();
        ArrayList<Integer> ps = new ArrayList<Integer>();
//        4.发牌(编号)
        for (int i = 0; i< cardsBox.size(); i++) {
            //先取出牌
            Integer s = cardsBox.get(i);
            if (i >= 51) {
                ps.add(s);
            } else {
                if (i % 3 == 0) {
                    p1.add(s);
                } else if (i % 3 == 1) {
                    p2.add(s);
                } else {
                    p3.add(s);
                }
            }
        }
        System.out.println(cardsBox);
//        5.排序(编号)
        System.out.println(cardsBox);
        Collections.sort(p1);
        Collections.sort(p2);
        Collections.sort(p3);
        Collections.sort(ps);
//        6.转牌(把编号转成对应的牌)
        lookCards(p1, map);
        lookCards(p2, map);
        lookCards(p3, map);
        lookCards(ps, map);
    }
    //转牌,看牌
    private static void lookCards(ArrayList<Integer> p1, Map<Integer, String> map) {
        //1.遍历集合取出所有的编号
        for (Integer carId : p1) {
            String s = map.get(carId);
            System.out.print(s+" ");
        }
        System.out.println();
    }
    /**
     * 目前是按照升序排序的
     * 修改成降序
     *      方法1:倒叙遍历玩家的编号
     *      方法2:定义map集合时牌越大编号越小
     *      方法3:Collection.sort(集合,自定义比较器)
     */
}
  注意: 
		    sort(List<T> list);//根据元素的自然顺序对指定列表按升序进行排序
                    
                
                
            
        
浙公网安备 33010602011771号