2019-01-13

作者: DreamPath | 来源:发表于2019-01-13 22:40 被阅读7次

基于Map集合重点整理

Map集合

1.1Map集合概念
  • Map集合是一种存放关系对象的对象的双列集合。
img.png
1.2Map集合的常用子类

HashMap<K,V>

  • 1.数据存储方式:哈希表结构。
  • 2.存储情况:无序
  • 3.保证键的唯一性方式:需要重写键的hashCode()方法、equals()方法。

LinkedHashMap<K,V>,是HashMap的一个子类。

  • 1.数据存储方式:哈希表结构+链表结构
    存储数据采用的哈希表结构+链表结构。
    (1.链表结构:保证元素的存取顺序一致。
    (2.哈希表结构:保证的键的唯一、不重复。
  • 3.同样需要重写键的 hashCode()方法、equals()方法

注意:K, V泛型类型可以一致,也可以不一致。

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

/**
 * @author lx
 * @date 2019/1/3 - 17:25
 * public V put(K key, V value) :  把指定的键与指定的值添加到Map集合中。
 * public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
 * public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
 * boolean containsKey(Object key) 判断集合中是否包含指定的键。
 * public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
 * public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
 */
public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<String, String> hashMap = new HashMap<>();
        //添加元素
        hashMap.put("冯小刚", "范冰冰");
        hashMap.put("李晨", "范冰冰");
        //如果键相同,值不同时,直接会覆盖前面的Value值。
        hashMap.put("冯小刚", "徐帆");

        hashMap.put("冯绍峰", "赵丽颖");
        hashMap.put("霍建华", "林心如");
        hashMap.put("杨幂", "刘恺威");

        System.out.println(hashMap);
        //{冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰, 杨幂=刘恺威}
            //通过Key删除元素
            hashMap.remove("杨幂");
        System.out.println(hashMap);
        //{冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰}

        //获取指定键key的value值
        String s = hashMap.get("霍建华");
        System.out.println(s);//林心如

        //判断集合中是否包含指定键
        System.out.println(hashMap.containsKey("杨幂"));//在这之前已经被删除了,返回false

        //判断集合中是否含有指定value值(一般很少用)
        System.out.println(hashMap.containsValue("范冰冰"));//true

        //获取集合中的所有键,并存储到集合中
        Set<String> set=hashMap.keySet();
        System.out.println(set);//[冯绍峰, 霍建华, 冯小刚, 李晨]

            //获取  键值对  对象的集合
        Set<Map.Entry<String,String>> set1=hashMap.entrySet();
        System.out.println(set1);//[冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰]

        //遍历获取到的键值对的集合
        for (Map.Entry<String,String> ss:set1) {
            System.out.println(ss);
            /*
            冯绍峰=赵丽颖
            霍建华=林心如
            冯小刚=徐帆
            李晨=范冰冰
             */
        }
    }
}
Entry键值对对象
  • Key(键)+Value(值)=Map集合中的Entry项。
  • Entry将键值对封装成了键值对 对象。方便了我们从每一个Entry对象获取对应的与对应的
Map集合遍历键值对的方式

通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。

    1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。使用entrySet()方法。
    1. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
    1. 通过键值对(Entry)对象,获取Entry对象中的键与值。使用getkey() 方法和getValue()。
package hashMap_demo;

import java.util.HashMap;

import java.util.Map;
import java.util.Set;

/**
 * public K getKey() :获取Entry对象中的键。
 * public V getValue() :获取Entry对象中的值。
 * 在Map集合中也提供了获取所有Entry对象的方法:
 * public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
 */
public class EntryDemo {

    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(20, "aa");
        map.put(18, "bb");
        map.put(20, "dd");
        map.put(25, "gg");
        map.put(28, "cc");

//      使用hashMap集合对象调用entrySet方法获取Set的所有的entry对象,
        Set<Map.Entry<Integer, String>> entries = map.entrySet();

        for (Map.Entry<Integer, String> entry : entries) {
            int aInt = entry.getKey();
            String ss = entry.getValue();
            System.out.println(aInt + "cp是" + ss);
            //输出结果:
            //18cp是bb
            //20cp是dd
            //25cp是gg
            //28cp是cc

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

        }
    }
}
HashMap存储自定义类型键值
  • 练习:每位学生(姓名,年龄)都有自己的家庭住址。
  • 那么,既然有对应关系,则将学生对象和家庭住址存储到 map集合中。学生作为键, 家庭住址作为值。
  • 注意,学生姓名相同并且年龄相同视为同一名学生。
package hashMap_demo;

import java.util.Objects;

/**
 * @author lx
 * @date 2019/1/13 - 18:15
 */
public class Student {
    //创建变量
    private String name;
    private int age;
//默认构造器
    public Student() {
    }
//有参构造器
    public Student(String name, int age) {
        this.name=name;
        this.age=age;
    }
//setter getter方法
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge() {
        this.age = age;
    }
//equals方法首先判断传入的是否与本类中的相同,相同则返回true
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }//其次再判断如果为空或者类名不同,则直接返回false
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        //将Object类型强转为Student类型,构成内容给的比较
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, age);
    }
//重写toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
//保证键值的唯一性
    @Override
    public int hashCode() {
        return Objects.hash(name,age);
    }
}

定义测试类:

package hashMap_demo;

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

/**
 * @author lx
 * @date 2019/1/13 - 18:39
 */
public class Entry_Demo {
    public static void main(String[] args) {
        Map<Student,String> map=new HashMap<>();
        map.put(new Student("赵颖", 20), "河北");
        map.put(new Student("陈爽", 25), "湖南");
        map.put(new Student("张亚蓝", 29), "厦门");
        map.put(new Student("吕小童", 32), "陕西");
        map.put(new Student("赵颖",20),"山西");
        Set<Student> studentSet=map.keySet();
        for (Student key:studentSet
             ) {
            String sss = map.get(key);
            System.out.println(key+"的住址是"+sss);
            /*输出结果:
              Student{name='赵颖', age=20}的住址是山西
              Student{name='陈爽', age=25}的住址是湖南
              Student{name='吕小童', age=32}的住址是陕西
              Student{name='张亚蓝', age=29}的住址是厦门*/
        }
    }

}

1.当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法。
2.如果要保证map中存放的key和取出的顺序一致,可以使用 java.util.LinkedHashMap 集合来存放。

LinkedHashMap

它是HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。
特点:有序,不可重复

package hashMap_demo;

import java.util.LinkedHashMap;
/**
 * @author lx
 * @date 2019/1/13 - 17:12
 */
public class LinkedHashSetDemo {
    public static void main(String[] args) {
        LinkedHashMap<String,String> linkedHashMap=new LinkedHashMap<>();
                linkedHashMap.put("赵丽颖","冯绍峰");
                linkedHashMap.put("金玟岐","金玟岐");
                linkedHashMap.put("咪咕","王少");
                linkedHashMap.put("卡罗","扎西");
                linkedHashMap.put("赵丽颖","李易峰");
        System.out.println(linkedHashMap);
        /*
        {赵丽颖=李易峰, 金玟岐=金玟岐, 咪咕=王少, 卡罗=扎西}
         */
    }
}

计算一个字符串中每个字符出现次数

package hashMap_demo;

import java.util.HashMap;
import java.util.Scanner;

/**
 * @author lx
 * @date 2019/1/13 - 17:41
 * 需求:
 * 计算一个字符串中每个字符出现次数
 * 1.从控制台获取字符串
 * 2.创建一个集合,一个作为为字符,一个为次数
 * 3.将字符串转化为字符,逐个遍历,判断是否是第一次出现
 * 4如果是第一次出现,Integer设置为1,不是则先获取上一次的value值。再加一之后存放
 */
public class JiSuanZifuChuan {

    public static void main(String [] args){
        //从控制台录入字符串
        Scanner scanner=new Scanner(System.in);
        //获取字符串
        String next = scanner.nextLine();

        //创建一个集合,存储字符和次数
        HashMap<Character, Integer> hashMap = new HashMap<>();

        for (int i = 0; i < next.length(); i++) {
            //获取字符
            char c = next.charAt(i);
            if (!hashMap.containsKey(c)) {
                hashMap.put(c, 1);
            } else {
                //如果不是第一次,先取出来,然后再加一
                Integer integer = hashMap.get(c);

                hashMap.put(c, ++integer);
            }

        }
        System.out.println(hashMap);
    }
}
jdk9.0添加的优化

1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法。比如 HashSet,ArrayList等;
2:返回的集合是不可变的.

public class Demo01 {  
  public static void main(String[] args) {  
      List<String> list = new ArrayList<>();        
        list.add("abc");
        list.add("def");     
        list.add("ghi");   
     System.out.println(list);  //[abc, def, ghi]  
       }
 }
package hashMap_demo;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author lx
 * @date 2019/1/13 - 18:09
 */
public class HelloJDK9 {
    public static void main(String[] args) {
//        of方法设置后,集合不可变
        
        Set<String> str1 = Set.of("a", "b", "c");
//        str1.add("c");    这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
        System.out.println(str1);//[a, c, b]
        
        Map<String, Integer> str2 = Map.of("a", 1, "b", 2);
        System.out.println(str2);//{a=1, b=2}
        
        List<String> str3 = List.of("a", "b");
        System.out.println(str3);//[a, b]
    }
}

模拟斗地主洗牌发牌

  • 使用面向对象的方式实现斗地主洗牌发牌的操作
package douDiZhu;

import java.security.Key;
import java.util.*;

/**
 * @author lx
 * @date 2019/1/13 - 18:24
 *
 * 创建三个玩家
 * 
 * 创建牌
 * 构造牌盒
 * 洗牌
 * 发牌
 * 看牌
 *
 */
public class DouDiZhu {
    public static void main(String[] args) {
        //创建牌数组
        String [] as={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//        创建花色
        String [] poker_color={"♠","♦","♣","♥"};
            //创建牌盒
        Map<Integer,String> map=new LinkedHashMap<>();
       //初始化索引为1
        int count=1;

        for (int i = 0; i <as.length; i++) {
            for (int j = 0; j <poker_color.length; j++) {
                //将牌的数字和花色组合遍历
                String sm=as[i]+poker_color[j];
                //索引自增
                map.put(count++,sm);
            }
        }
        //添加大王小王牌面
        map.put(count++,"小王🃏");
        map.put(count++,"大王🃏");
                //将map集合对象的键存放在set集合中
            Set<Integer> set=map.keySet();
            //创建ArrayList集合
        ArrayList<Integer> arrayList=new ArrayList<>();
        //将set集合元素全部存入ArrayList集合中
        arrayList.addAll(set);

        //洗牌
        Collections.shuffle(arrayList);
//        发牌
//          创建三个玩家和三张底牌的索引
        ArrayList<Integer> Wanjia1=new ArrayList<>();
        ArrayList<Integer> wanjia2=new ArrayList<>();
        ArrayList<Integer> wanjia3=new ArrayList<>();
        ArrayList<Integer> dipaiNo=new ArrayList<>();
                //给每个玩家发牌
        for (int i = 0; i <arrayList.size() ; i++) {
            Integer integer=arrayList.get(i);
            if (i>=51) {
                dipaiNo.add(integer);
            } else{
                if (i%3==0){
                Wanjia1.add(integer);
                } else if (i%3==1) {
                    wanjia2.add(integer);
                }else {
                    wanjia3.add(integer);
                }}
        }
                //将手中的牌按照大小排序
        Collections.sort(Wanjia1);
        Collections.sort(wanjia2);
        Collections.sort(wanjia3);
        Collections.sort(dipaiNo);

            //创建玩家的牌面集合
        ArrayList play1=new ArrayList();
        ArrayList play2=new ArrayList();
        ArrayList play3=new ArrayList();
        ArrayList dipai=new ArrayList();
            //遍历 根据键来获得值(牌面)
        for (Integer is:Wanjia1) {
            String value = map.get(is);
            play1.add(value);
        } for (Integer is:wanjia2) {
            String value = map.get(is);
            play2.add(value);
        } for (Integer is:wanjia3) {
            String value = map.get(is);
            play3.add(value);
        }for (Integer is:dipaiNo) {
            String value = map.get(is);
            dipai.add(value);
        }
        //看牌
        System.out.println("哈儿"+play1);
        System.out.println("逗逼" +play2);
        System.out.println("傻子"+play3);
        System.out.println("底牌"+dipai);
    }
}

相关文章

网友评论

    本文标题:2019-01-13

    本文链接:https://www.haomeiwen.com/subject/ngkrdqtx.html