Java-集合框架-Map

1. Map概述

Map集合特点:该集合存储键值对。一对一对往里面存,而且要保证键的唯一性。

  1. Hashtable
  2. HashMap
  3. TreeMap

添加 put(key, value); putAll(Map<? extends K, ? extends V>)
删除 clear(); remove(Onject key)
判断 containsKey(Object key); containsValue(Object value);
获取 get(Object key); size(); value(); entrySet(); keySet();

2. Map子类对象特点

Hashtable: 底层是哈希表数据结构,不可以存入null键、null值,该集合是同步的,jdk1.0,效率低
HashMap: 底层是哈希表数据结构,允许存入null键、null值,该集合是不同步的,jdk1.2,效率高
TreeMap: 底层是二叉树数据结构,线程不同步,可以给map集合中的键进行排序

Map和Set很像,其实Set底层就是使用了Map集合。

3.

添加元素: 如果出现添加相同的键,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖的值。

package Map;

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

public class MapDemo {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();

        //添加元素
        map.put("01","gy");
        map.put("02","gy");
        map.put("03","gy");

        System.out.println("containsKey:"+map.containsKey("01"));
        System.out.println("remove:"+map.remove("01"));

        map.put("02","gy1");
        System.out.println("get:"+map.get("02"));
        // 可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断

        //获取Map中所有的值
        Collection<String> coll = map.values();
        System.out.println(coll);
    }
}

4. Map-keySet

Map集合的这两种取出方式:

第一种方式: Set<k> keySet():返回此映射中包含的键的Set视图,将Map中所有的键存入到Set集合中,因为Set具备迭代器,所以可以使用迭代的方式取出所有的键,再根据get方法,获取每一个键对应的值。

Map集合取出原理:将Map集合转成Set集合,再通过迭代器取出。

package Map;

import java.util.*;

public class MapDemo2 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();

        map.put("01","gy1");
        map.put("03","gy3");
        map.put("02","gy2");

        //先获取map集合的所有键的Set集合,keySet()
        Set<String> keySet = map.keySet();

        Iterator<String> it = keySet.iterator();
        while (it.hasNext()){
            String s = it.next(); //获取key
            System.out.println("key:"+s+"...value:"+map.get(s));
        }
    }
}

输出结果:

key:01...value:gy1
key:02...value:gy2
key:03...value:gy3

5. Map-entrySet

第二种方式: Set<Map.Entry<K, V>> entrySet():返回此映射中包含的映射关系的Set视图。 而这个关系的数据类型就是:Map.Entry

关系对象Map.Entry获取到后,就可以通过Map.Entry中的getKey()getValue()获取到关系中的键和值

package Map;

import java.util.*;

public class MapDemo2 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();

        map.put("01","gy1");
        map.put("03","gy3");
        map.put("02","gy2");

        //将Map集合中的映射关系取出,存入到Set集合中
        Set<Map.Entry<String,String>> entrySet = map.entrySet();


        Iterator<Map.Entry<String,String>> it = entrySet.iterator();
        while (it.hasNext()){
            Map.Entry<String,String> me = it.next(); //获取key
            System.out.println("key:"+me.getKey()+"...value:"+me.getValue());
        }
    }
}

结果:

key:01...value:gy1
key:02...value:gy2
key:03...value:gy3

Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口。

interface Map{
	public static interface Entry{
		public abstract Object getKey();
		public abstract Object getValue();
	}
}

class HashMap implements Map{
	class Haha implements Map.Entry{
		public Object getKey(){}
		public Object getValue(){}
	}	
}

6. Map练习题

题目: 每一个学生都有对应的归属地。
学生Student, 地址String
学生属性:姓名、年龄。
注意:姓名和年龄相同视为同一个学生。保证学生的唯一性。

  1. 描述学生
  2. 定义Map容器,将学生作为键,地址作为值,存入
  3. 获取Map集合中的内容
package Map;

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

class Student{
    private String name;
    private int age;
    public Student(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;
    }

    public String toString(){
        return "("+name+","+age+")";
    }

    public int hashCode(){
        return name.hashCode()+age*10;
    }

    public boolean equals(Object obj){
        if(obj instanceof Student){
            Student s = (Student)obj;
            return this.name.equals(s.name) && this.age == s.age;
        }
        throw new ClassCastException("类型不匹配");
    }
}

public class MapTest {
    public static void main(String[] args) {
        Map<Student, String> map = new HashMap<Student, String>();
        map.put(new Student("shh1",1),"Wuhan");
        map.put(new Student("shh1",1),"Nanjing");
        map.put(new Student("shh3",3),"Beijing");

        // 第一种取出方式
        System.out.println("第一种取出方式:");
        Set<Student> ketSet = map.keySet();
        Iterator<Student> it1 = ketSet.iterator();
        while (it1.hasNext()){
            Student stu = it1.next();
            String addr = map.get(stu);
            System.out.println(stu.toString()+" in "+addr);
        }

        //第二种取出方式
        System.out.println("第二种取出方式:");
        Set<Map.Entry<Student,String>> entrySet = map.entrySet();
        Iterator<Map.Entry<Student,String>> it2 = entrySet.iterator();
        while (it2.hasNext()){
            Map.Entry<Student,String> me = it2.next();
            Student stu = me.getKey();
            String addr = me.getValue();
            System.out.println(stu.toString()+" in "+addr);
        }
    }
}

输出结果:

第一种取出方式:
(shh3,3) in Beijing
(shh1,1) in Nanjing
第二种取出方式:
(shh3,3) in Beijing
(shh1,1) in Nanjing

7. TreeMap练习题

题目: 对学生对对象进行升序排序。按照姓名

因为数据是以键值对形式存在的。所以要使用可以排序的Map集合,TreeMap

package TreeMap;

import java.util.*;

class Student{
    private String name;
    private int age;
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }
    public String toString(){
        return "( name:"+name+", age:"+age+")";
    }
}

class StuNameComparator implements Comparator<Student> {
    public int compare(Student s1, Student s2){
        int num = s1.getName().compareTo(s2.getName());
        if(num == 0) return s1.getAge() - s2.getAge();
        return num;
    }
}
public class TreeMapTest {
    public static void main(String[] args) {
        Map<Student, String> treeMap = new TreeMap<Student, String>(new StuNameComparator());

        treeMap.put(new Student("shh1",10),"Wuhan");
        treeMap.put(new Student("shh3",3),"Nanjing");
        treeMap.put(new Student("shh2",12),"Beijing");
        treeMap.put(new Student("shh2",12),"Shanghai");

        Set<Map.Entry<Student, String>> entrySet = treeMap.entrySet();
        Iterator<Map.Entry<Student, String>> it = entrySet.iterator();
        while (it.hasNext()){
            Map.Entry<Student, String> me = it.next();
            Student stu = me.getKey();
            String addr = me.getValue();
            System.out.println(stu.toString()+" in "+addr);
        }
    }
}

输出结果:

( name:shh1, age:10) in Wuhan
( name:shh2, age:12) in Shanghai
( name:shh3, age:3) in Nanjing

8. 字母出现的次数

题目: “sdfgdhaodygvguaschf” 获取该字符串中字母出现的次数。希望打印的结果:a(2) c(1)…

分析: 通过结果发现,每一个字母都有对应的次数。说明字母和数字之间有映射关系。

注意了,当发现具有映射关系,可以使用Map集合,因为Map集合中存放就是映射关系。
什么时候使用Map集合? 当数据之间存在这重映射关系时,就要先想到Map集合。

思路:

  1. 将字符串转化成字符数组,因为要对每一个字符进行操作
  2. 定义一个Map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。
  3. 遍历字符数组。将每一个字母作为键去查Map集合,如果返回null,将该字母和1存入Map集合中;如果返回的不是null,说明该字母在Map集合中已经存在,那么就获取该字母对应的次数,并进行自增,然后将该字母和自增后的次数存入到Map集合中,覆盖原来键对应的值。
  4. 将Map集合中的数据变成指定的字符串形式返回
package TreeMap;

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

public class TreeMapTest2 {
    public static void main(String[] args) {
        Map<Character, Integer> map = statsNum("sdfgdhaodygvguaschf");
        Set<Map.Entry<Character,Integer>> entrySet = map.entrySet();
        Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();
        while (it.hasNext()){
            Map.Entry<Character,Integer> me = it.next();
            char c = me.getKey();
            int count = me.getValue();
            System.out.println(c+"("+count+")");
        }
    }

    public static Map<Character,Integer> statsNum(String s){
        Map<Character,Integer> map = new TreeMap<>(); // 注意:泛型里面的存的都是对象,所以不能使用char和int
        char[] strs = s.toCharArray();
        int len = s.length();
        char c;
        for(int i=0; i<len; i++){
            c = strs[i];
            if(map.get(c) == null){
                map.put(c,1);
            }
            else{
                int count = map.get(c);
                count++;
                map.put(c,count);
            }
        }
        return map;
    }
}

输出结果:

a(2) c(1) d(3) f(2) g(3) h(2) o(1) s(2) u(1) v(1) y(1) 

9. Map集合的扩展

Map集合被使用是因为具备映射关系。

“Wuhan” "01" "shh01"
“Wuhan” "02" "shh02"
“Nanjing” "01" "gy01"
“Nanjing” "01" "gy02"
package Map;

import java.util.*;

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Map<String, String>> residence = new HashMap<>();
        Map<String, String> people1 = new HashMap<String, String>();
        Map<String, String> people2 = new HashMap<String, String>();

        people1.put("01","shh1");
        people1.put("02","shh2");

        people2.put("01","gy1");
        people2.put("02","gy2");

        residence.put("Wuhan",people1);
        residence.put("Nanjing",people2);

        System.out.println("_______________1_______________");
        getPeopleInfo(people1);
        System.out.println("_______________2_______________");
        getPeopleInfo(people2);

        //遍历residence集合,获取所有的城市
        System.out.println("_______________3_______________");
        Iterator<String> it = residence.keySet().iterator();
        while (it.hasNext()){
            String city = it.next();
            System.out.println(city);
            Map<String, String> people = residence.get(city);
            getPeopleInfo(people);
        }
    }

    public static void getPeopleInfo(Map<String, String> cityMap){
        Set<String> keySet = cityMap.keySet();
        Iterator<String> it = keySet.iterator();
        while (it.hasNext()){
            String id = it.next();
            String name = cityMap.get(id);
            System.out.println(id+":"+name);
        }

    }
}

输出:

_______________1_______________
01:shh1
02:shh2
_______________2_______________
01:gy1
02:gy2
_______________3_______________
Wuhan
01:shh1
02:shh2
Nanjing
01:gy1
02:gy2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值