Map<k,v>集合、HashMap<k,v>集合、LinkedHashMap<k,v>、HashTable<k,v>集合、Map集合在JDK9的新特性

Map<k,v>集合

java.util.Map<k,v>集合

Map集合特点:

1.Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)

2.Map集合中,key和value的数据类型可以相同,也可以不同

3。Map集合中的元素,key时不允许重复,value是可以重复的

4.Map集合中的元素,key和value是一一对应的

Map集合的两个子类集合:

HashMap<k,v>集合

Java.util.HashMap<k,v>集合 implement Map<k,v>接口

HashMap集合的特点:

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

jdk1.8之前:数组+单向链表

jdk1.8之后:数组+单向链表/红黑树(链表的长度超过8):提高查询速度

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

LinkedHashMap<k,v>集合

java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合

LinkedHashMap集合的特点:

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

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

Map接口中常用的方法:
V put(K key, V value);//将key与之对应的value,放入Map集合中

返回值:

存储键值对的时候,key不重复,返回值V是null

存储键值对的时候,key重复,会用新value来替换已经存储的value,并返回这个已经存储的value

V remove(Object key);//删除key所对应的value,并返回value

返回值:

key存在,返回删除的value

key不存在,返回null

V get(Object key);//获取key所对应的value

返回值:

key存在,返回对应的value

key不存在,返回null

boolean containsKey(Object key);//Map集合中是否包含指定的key,有true,无false
package mymap;

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

//测试Map接口常用方法
public class TestMap01 {
    public static void main(String[] args) {
        Map<String,Integer> hashMap = new HashMap<>();

        hashMap.put("小明",12);
        hashMap.put("小红",5);
        hashMap.put("小刚",16);
        hashMap.put("小王",22);
        hashMap.put("小张",32);
        System.out.println(hashMap);//{小刚=16, 小明=12, 小王=22, 小红=5, 小张=32}

        Integer b1 = hashMap.remove("小张");
        System.out.println(b1);//32
        Integer b2 = hashMap.remove("老李");
        System.out.println(b2);//null
        System.out.println(hashMap);//{小刚=16, 小明=12, 小王=22, 小红=5}

        Integer c1 = hashMap.get("小明");
        System.out.println(c1);//12
        Integer c2 = hashMap.get("老刘");
        System.out.println(c2);//null

        boolean d1 = hashMap.containsKey("小刚");
        System.out.println(d1);//true
        boolean d2 = hashMap.containsKey("秦始皇");
        System.out.println(d2);//false
    }
}
Map集合的第一种遍历方式:通过键找值的方式

Map集合的方法:

Set<K> keySet();//将Map集合中所有的key存储到set集合中,并返回

实现步骤:

1.使用Map集合中的方法keySet(),将Map集合中所有的key取出来,存储到一个set集合里面

2.遍历set集合,获取Map集合中的每一个key

3.通过Map集合的方法get(key),通过key找到value

Map<String,Integer> hashMap = new HashMap<>();

hashMap.put("小明",12);
hashMap.put("小红",5);
hashMap.put("小刚",16);
hashMap.put("小王",22);
hashMap.put("小张",32);

/* Set<String> set = hashMap.keySet();
        for (String s : set) {
            System.out.print(hashMap.get(s)+"\t");
        }
        */
        //简化版
        for (String s : hashMap.keySet()) {
            System.out.print(hashMap.get(s)+"\t");
        }
Map集合的第二种遍历方式:使用Entry对象遍历

Map集合中的方法:

Set<Map.Entry<K, V>> entrySet();//将Map集合中所有的键值对对象Entry,放入set集合中,并返回

实现步骤:

1.使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个set集合中

2.遍历set集合,获取每一个Entry对象

3.使用Entry对象的方法getKey()和getValue()获取键与值

Map<String,Integer> hashMap = new HashMap<>();

hashMap.put("小明",12);
hashMap.put("小红",5);
hashMap.put("小刚",16);
hashMap.put("小王",22);
hashMap.put("小张",32);
 /*Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            System.out.print(entry.getKey()+"="+entry.getValue()+"\t");
        }*/
        //简化版
        for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
            System.out.print(entry.getKey()+"="+entry.getValue()+"\t");
        }
HashMap存储自定义类型键值

Map集合保证key是唯一的:

作为key的元素,必须重写hashCode方法和equal方法,以保证key的唯一

package mymap;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

//用hashmap存储自定义类型
public class TestHashMap01 {
    public static void main(String[] args) {
        HashMap<Person,String> hashMap = new HashMap<>();
        hashMap.put(new Person("小张",23),"上海");
        hashMap.put(new Person("小王",33),"北京");
        hashMap.put(new Person("小刘",43),"广州");
        hashMap.put(new Person("小张",23),"上海");//和第一个添加的key相同
        //Map集合保证key是唯一的, 作为key的元素,必须重写hashcode方法和equals方法,以保证key的唯一
        //若不重写,输出为Person{name='小刘', age=43}-->广州Person{name='小王', age=33}-->北京Person{name='小张', age=23}-->上海Person{name='小张', age=23}-->上海
        //Map里面有两个key相同,不允许
        for (Map.Entry<Person, String> entry : hashMap.entrySet()) {
            Person key = entry.getKey();
            String value = entry.getValue();
            //重写hashcode方法和equals方法后
            System.out.print(key+"-->"+value);//Person{name='小刘', age=43}-->广州Person{name='小王', age=33}-->北京Person{name='小张', age=23}-->上海
        }
    }
}
class Person{
    private String name;
    private int age;

    public Person() {
    }

    public 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 "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    //Map集合保证key是唯一的, 作为key的元素,必须重写hashcode方法和equals方法,以保证key的唯一
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
LinkedHashMap<k,v>集合

java.util.LinkedHashMap<k,v> extends HashMap<k,v>

Map接口的哈希表和链表列表的实现,具有可预知的迭代性

底层原理:

哈希表+链表(记录元素的顺序)

package mymap;

import java.util.LinkedHashMap;

public class TestLinkedHashMap01 {
    public static void main(String[] args) {
        LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put(1, "渐渐");
        linkedHashMap.put(2, "哈哈");
        linkedHashMap.put(3, "好好");
        linkedHashMap.put(1, "微微");//Integer类中重写了hashcode方法和equals方法,Map的key唯一,重写,将第一个覆盖了

        for (Integer key : linkedHashMap.keySet()) {
            System.out.print(key + "-->" + linkedHashMap.get(key) + "\t");//1-->微微 2-->哈哈 3-->好好 ,按添加顺序,LinkedHashMap是有顺序的,存取顺序相同
        }
    }
}
HashTable<k,v>集合

java.util.HashTable<k,v>集合 implements Map<k,v>接口

HashTable:底层是一个哈希表,是一个线程安全集合,是单线程集合,速度慢

HashMap:底层是一个哈希表,是一个线程不安全集合,是多线程集合,速度快

hashMap集合(之前学的所有集合):可以存储null值,null键

HashTable集合,不能存储null键,null值

HashTable和vector集合一样,在jdk1.2版本之后被更先进的集合所替代(HashMap,arrayList)

HashTable的子类properties依然活跃在历史的舞台

properties集合是一个唯一和IO流相结合的集合

练习:

package mymap;

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

//获取用户输入字符串中每个字符出现的次数
/*思路:
* 1.从输入台中获取字符串,转化为字符数组
* 2.创建一个Map集合,key代表字符,value代表次数
* 3.遍历字符数组,判断Map集合中key是否有该字符,有value+1,无往Map中添加
* 4.遍历Map集合,输出key和value*/
public class Practice01 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个英文字符:");
        String str = scanner.nextLine();

        char[] chars = str.toCharArray();

        HashMap<Character,Integer> hashMap = new HashMap<>();
        for (char c :chars){
            int value = 0;
            if (hashMap.containsKey(c)){
                value = hashMap.get(c);
                value++;
            }else {
                value = 1;
            }
            hashMap.put(c,value);
        }

        for (Map.Entry<Character, Integer> entry : hashMap.entrySet()) {
            System.out.println(entry.getKey()+"出现的次数:"+entry.getValue());
        }

    }
}

package mymap;

import java.util.*;

//模拟斗地主,洗牌发牌过程,在玩家手中牌要有顺序
//自己写的版本
public class Practice02 {
    public static void main(String[] args) {
        //54张扑克牌
        LinkedHashMap<Integer,String> pokers = new LinkedHashMap<>();
        //存储大小王
        pokers.put(0,"JOKER");
        pokers.put(1,"joker");
        //存储其他52张牌
        ArrayList<String> colors = new ArrayList<>();
        Collections.addAll(colors,"♠","♥","♦","♣");
        ArrayList<String> nums = new ArrayList<>();
        Collections.addAll(nums,"2","A","K","Q","J","10","9","8","7","6","5","4","3");

        int i=2;
        for (String num : nums) {
            for (String color : colors) {
                pokers.put(i++,color+num);
            }
        }
        System.out.println(pokers);
        //将pokers Map集合中key存储到List集合中
        ArrayList<Integer> keyList = new ArrayList<>();

        for (Map.Entry<Integer, String> entry : pokers.entrySet()) {
            keyList.add(entry.getKey());
        }
        System.out.println(keyList);
        //打乱key顺序,打乱牌顺序
        Collections.shuffle(keyList);
        System.out.println(keyList);
        //发牌
        ArrayList<String> p1 = new ArrayList<>();
        ArrayList<String> p2 = new ArrayList<>();
        ArrayList<String> p3 = new ArrayList<>();
        ArrayList<String> bottom = new ArrayList<>();
        ArrayList[] arr = {p1,p2,p3,bottom};

        for (int i1 = 0; i1 < keyList.size(); i1++) {
            if (i1 >= 51) {
                bottom.add(pokers.get(keyList.get(i1)));
            }else if (i1 % 3 ==  0){
                p1.add(pokers.get(keyList.get(i1)));
            }else if (i1 % 3 ==  1){
                p2.add(pokers.get(keyList.get(i1)));
            }else if (i1 % 3 ==  2){
                p3.add(pokers.get(keyList.get(i1)));
            }
        }

        //对每个人手中的牌进行排序
        for (ArrayList arrayList : arr) {
            Collections.sort(arrayList, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    int key1 = 0;
                    int key2 = 0;
                    for (Map.Entry<Integer, String> entry : pokers.entrySet()) {
                        if (entry.getValue().equals(o1) ){
                            key1 = entry.getKey();
                        }
                        if (entry.getValue().equals(o2)){
                            key2 = entry.getKey();
                        }
                    }
                    return key1 - key2;
                }
            });
        }

        //查看每一个人手中的牌,和底牌
        for (int i1 = 0; i1 < arr.length; i1++) {
            if (i1 == arr.length - 1){
                System.out.println("底牌为:");
            }else {
                System.out.println("第"+(i1+1)+"位玩家的牌为:");
            }
            for (int i2 = 0; i2 < arr[i1].size(); i2++) {
                System.out.print(arr[i1].get(i2)+"\t");
            }
            System.out.println();
        }
    }
}
package mymap;

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

//老师写的版本
public class Practice03 {
    public static void main(String[] args) {
        //存储54张牌,和54张牌索引
        HashMap<Integer,String> pokers = new HashMap<>();
        ArrayList<Integer> pokersIndex = new ArrayList<>();
        //存储大小王
        int index = 0;
        pokers.put(index,"JOKER");
        pokersIndex.add(index);
        index++;
        pokers.put(index,"joker");
        pokersIndex.add(index);
        index++;
        //存储其他52张牌
        ArrayList<String> colors = new ArrayList<>();
        Collections.addAll(colors,"♠","♥","♦","♣");
        ArrayList<String> nums = new ArrayList<>();
        Collections.addAll(nums,"2","A","K","Q","J","10","9","8","7","6","5","4","3");
        for (String num : nums) {
            for (String color : colors) {
                pokers.put(index,color+num);
                pokersIndex.add(index);
                index++;
            }
        }
        System.out.println(pokers);
        System.out.println(pokersIndex);

        //洗牌
        Collections.shuffle(pokersIndex);
        System.out.println(pokersIndex);

        //发牌
        ArrayList<Integer> p1 = new ArrayList<>();
        ArrayList<Integer> p2 = new ArrayList<>();
        ArrayList<Integer> p3 = new ArrayList<>();
        ArrayList<Integer> bottom = new ArrayList<>();

        for (int i = 0; i < pokersIndex.size(); i++) {
            if (i >= 51) {
                bottom.add(pokersIndex.get(i));
            }else if (i % 3 == 0) {
                p1.add(pokersIndex.get(i));
            }else if (i % 3 == 1) {
                p2.add(pokersIndex.get(i));
            }else if (i % 3 == 2) {
                p3.add(pokersIndex.get(i));
            }
        }

        //对每个人和底牌进行排序
        Collections.sort(p1);
        Collections.sort(p2);
        Collections.sort(p3);
        Collections.sort(bottom);

        //查看每个人手中的牌和底牌
        ArrayList[] arr = {p1,p2,p3,bottom};
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1){
                System.out.println("底牌为:");
            }else {
                System.out.println("第"+(i+1)+"位玩家的牌为:");
            }

            for (int i1 = 0; i1 < arr[i].size(); i1++) {
                System.out.print(pokers.get(arr[i].get(i1))+"\t");
            }
            System.out.println();
        }
    }
}
JDK9的新特性

List接口,Set接口,Map接口:里面增加了一个静态方法of,可以给集合一次性添加多个元素

static list of (E...elements)

使用前提:

当集合中存储的元素个数已经确定了,不再改变时使用

注意:

1.of方法只适用于List接口,Set接口,Map接口,不适应于接口的实现类

2.of方法的返回值是一个不可改变的集合,集合不能使用add,put方法添加元素,会抛出异常

3.set接口和map接口在调用of方法的时候,不能有重复的元素,否则报错

posted @ 2020-08-13 11:29  DannyBoy~  阅读(147)  评论(0编辑  收藏  举报