Map集合

7、Map接口

  Collection、Set、List接口都属于单值的操作,而Map中的每个元素都使用key——>value的形式存储在集合中。

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

      

 Map的三个常用实现类


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

HashMap示例:

/**
 Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。

 1,添加。
    V | put(K key, V value)
    void | putAll(Map<? extends K,? extends V> m)

 2,删除。
    void | clear()
    V | remove(Object key)

 3,判断。
    boolean | containsValue(Object value)
    boolean | containsKey(Object key)
    boolean | isEmpty()

 4,获取。
    V | get(Object key)
    int | size()
    Collection<V> | values()
    Set<Map.Entry<K,V>> | entrySet()
    Set<K> | keySet()

 Map的三个常用实现类
 |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
 |--HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。
 |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。


 和Set很像。
 其实大家,Set底层就是使用了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>();

        // 添加 会返回被覆盖的值,
        // 相同的键,后添加的值将会覆盖原有的值
        // 键和值都可存入null
        map.put("01","lisi1");
        System.out.println(map.put("02","lisi2"));  // null
        System.out.println(map.put("02","lisi002"));  // lisi2
        map.put("03","lisi1");
        map.put("04","lisi4");
        map.put(null,null); // 键和值都可存入null
        System.out.println(map);  // {01=lisi1, 02=lisi002, 03=lisi3, 04=lisi4}

        //删除
//        System.out.println("remove:"+map.remove("01"));  // 删除会返回删除的值
//        map.clear();  // 清空

        //判断
        System.out.println(map.containsKey("010"));  // true 是否包含这个key
        System.out.println(map.containsValue("lisi1"));  //true 是否包含这个值(一个或多个)
        System.out.println(map.isEmpty());  // 该集合是否为空

        // 获取
        System.out.println(map.get("01"));   // lisi1 获取值
        System.out.println(map.size());    // 获取集合大小
        Collection<String> values = map.values();  // 获取所有的值
        System.out.println(values);    // [lisi1, lisi002, lisi1, lisi4]

    }
}

entrySet 方法图例

 

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

/*
map集合的两种取出方式:
1,Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。
	所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。

	Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。


2,Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,
				而这个关系的数据类型就是:Map.Entry

				Entry其实就是Map中的一个static内部接口。
				为什么要定义在内部呢?
				因为只有有了Map集合,有了键值对,才会有键值的映射关系。
				关系属于Map集合中的一个内部事物。
				而且该事物在直接访问Map集合中的元素。



*/
public class MapDemo2 {

    public static void main(String[] args) {
//        KeySet_Method();
        Entry_Method();
    }

    public static void Entry_Method(){
        Map<String,String> map = new HashMap<String,String>();

        map.put("02","lisi02");
        map.put("03","lisi03");
        map.put("01","lisi01");
        map.put("05","lisi05");

        // entrySet() 将map 集合的映射关系存到set集合中  Map.Entry<String,String> 相当于一个映射关系类型
        Set<Map.Entry<String,String>> entrySet = map.entrySet();

        for (Iterator<Map.Entry<String, String>> it = entrySet.iterator(); it.hasNext();){
            Map.Entry<String,String> entry = it.next();  //获取一个映射关系
            // 通过映射关系中提供的getKey() 和 getValue() 获取键和值
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }

    public static void KeySet_Method() {
        Map<String,String> map = new HashMap<String,String>();

        map.put("02","lisi02");
        map.put("03","lisi03");
        map.put("01","lisi01");
        map.put("05","lisi05");

        // keySet:获取所有的键,返回Set
        Set<String> keys = map.keySet();

        for(Iterator it = keys.iterator(); it.hasNext();){
            //get(key) 获取每个键的值
            System.out.println(map.get(it.next()));
        }
    }
}

hashMap 练习

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

import java.util.*;

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



1,描述学生。

2,定义map容器。将学生作为键,地址作为值。存入。

3,获取map集合中的元素。

*/
public class MapTest {

    public static void main(String[] args) {
        Map<Student,String> map = new HashMap<Student,String>();
        map.put(new Student("lisi1",20),"beijing");
        map.put(new Student("lisi2",22),"beijing");
        map.put(new Student("lisi3",24),"nanjing");
        map.put(new Student("lisi4",20),"shanghai");
        //map.put(new Student("lisi4",20),"shanghai");  // 不会被添加

        // 遍历map keySet
//        for(Iterator<Student> it = map.keySet().iterator();it.hasNext();){
//            Student s = it.next();
//            String value = map.get(s);
//            System.out.println(s.toString()+":"+value);
//        }

        // EntrySet 遍历
        Set<Map.Entry<Student,String>> emptySet = map.entrySet();
        for (Iterator<Map.Entry<Student,String>> it = emptySet.iterator();it.hasNext();){
            Map.Entry<Student,String> entry = it.next();
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }
}

class Student{
    private String name;
    private int age;

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

    // 姓名和年龄相同的视为同一个学生。保证学生的唯一性,必须重写hashCode() 和 equals()
    public int hashCode(){
        return this.name.hashCode()+age*11;
    }

    public boolean equals(Object obj){
        if(!(obj instanceof Student)){
            throw new ClassCastException("类型不匹配");
        }
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age == s.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 "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

TreeMap练习(自定义比较)

按照年龄进行排序

package 集合.Map;

import java.util.*;

/*
每一个学生都有对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。保证学生的唯一性。
按照年龄进行排序
1. 让元素本身具备比较性
    实现Comparable接口,重写compareTo()
2. 自定义比较器
   定义一个类,实现Comparator接口,重写compare()
*/
public class TreeMapTest{

    public static void main(String[] args) {

        TreeMap<Student, String> tmap = new TreeMap<Student, String>(new NameComparator());
        tmap.put(new Student("lisi1",20),"beijing");
        tmap.put(new Student("lisi2",22),"beijing");
        tmap.put(new Student("lisi3",24),"nanjing");
        tmap.put(new Student("lisi3",22),"nanjing");
        tmap.put(new Student("lisi4",20),"shanghai");

        Set<Map.Entry<Student,String>> entrySet = tmap.entrySet();
        for (Iterator<Map.Entry<Student, String>> it = entrySet.iterator(); it.hasNext();){
            Map.Entry<Student,String> entry = it.next();  //获取一个映射关系
            // 通过映射关系中提供的getKey() 和 getValue() 获取键和值
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }
}

//通过姓名进行排序
class NameComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        int num = o1.getName().compareTo(o2.getName());
        if(num == 0){
            return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
        }
        return num;
    }
}

class Student implements Comparable<Student>{
    private String name;
    private int age;

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

    // 姓名和年龄相同的视为同一个学生。保证学生的唯一性,必须重写hashCode() 和 equals()
    public int hashCode(){
        return this.name.hashCode()+age*11;
    }

    public boolean equals(Object obj){
        if(!(obj instanceof Student)){
            throw new ClassCastException("类型不匹配");
        }
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age == s.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 "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student s) {
        int num = new Integer(this.age).compareTo(new Integer(s.age));
        if(num == 0){
            return this.name.compareTo(s.name);
        }
        return num;
    }
}

练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。

希望打印结果:a(1)c(2).....

/*
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。

希望打印结果:a(1)c(2).....

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

注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。


什么使用map集合呢?
当数据之间存在这映射关系时,就要先想map集合。

思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。

2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。

3,遍历字符数组。
	将每一个字母作为键去查map集合。
	如果返回null,将该字母和1存入到map集合中。
	如果返回不是null,说明该字母在map集合已经存在并有对应次数。
	那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。

4,将map集合中的数据变成指定的字符串形式返回。



*/
public class TreeMapTest2 {
    public static void main(String[] args) {
        String s = "abcabdef%cb--cdedd++ff";
        System.out.println(WordCount(s));
    }

    public static String WordCount(String s){
        Map<Character,Integer> map = new TreeMap<Character,Integer>();

        //1. 将字符串转换成字符数组
        char[] ch = s.toCharArray();

        //2.遍历字符串数组,判断map 中是否存在,
        for (int i = 0; i < ch.length; i++) {
            // 只统计字母
            if(!(ch[i] > 'a' && ch[i] < 'z' || ch[i] > 'A' && ch[i] < 'Z'))
                continue;
            Integer v = map.get(ch[i]);
            if (v == null){
                map.put(ch[i],1);
            }else {
                v++;
                map.put(ch[i],v);  // 会覆盖掉键相同的
            }
        }

        //3.输出a(1)c(2).....
        StringBuilder builder = new StringBuilder();

        Set<Map.Entry<Character,Integer>> entrySet = map.entrySet();
        for(Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();it.hasNext();){
            Map.Entry<Character,Integer> entry= it.next();
            builder.append(entry.getKey()+"("+entry.getValue()+")");
        }

        return builder.toString();

    }
}

map扩展

/*
map扩展知识。

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


"jiuyeban" "01" "wangwu";
"jiuyeban" "02" "zhaoliu";

一个学校有多个教室。每一个教室都有名称。


*/

import java.util.*;

public class MapDemo3 {
    public static void main(String[] args) {
        // 创建一个学校map
        Map<String, HashMap<String,String>> school = new HashMap<String, HashMap<String,String>>();

        //创建两个班级map
        HashMap<String,String> jichuban = new HashMap<String,String>();
        HashMap<String,String> jiuyeban = new HashMap<String,String>();

        school.put("就业班",jiuyeban);
        school.put("基础班",jichuban);
        jichuban.put("01","张三");
        jichuban.put("02","李四");
        jiuyeban.put("01","小明");
        jiuyeban.put("02","小强");

        // 获取每一个学生
        Set<Map.Entry<String, HashMap<String,String>>> entrySet = school.entrySet();
        for(Iterator<Map.Entry<String, HashMap<String,String>>> it = entrySet.iterator();it.hasNext();){
            Map.Entry<String, HashMap<String,String>> entry = it.next();
            // System.out.println(entry.getKey()+":"+entry.getValue());
            // 遍历每个班级 通过keySet()
            for (Iterator<String> it1 = entry.getValue().keySet().iterator();it1.hasNext();){
                String key = it1.next();
                String value = entry.getValue().get(key);
                System.out.println(key+":"+value);
            }
        }
    }
}

package 集合.Map;

/*
map扩展知识。

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

"yureban"   Student("01" "zhangsan");

"yureban" Student("02" "lisi");


一个学校有多个教室。每一个教室都有名称。


*/

import java.util.*;

public class MapDemo4 {
    public static void main(String[] args) {
        // 创建一个学校map
        Map<String, List<Student>> school = new HashMap<String, List<Student>>();

        //创建两个班级List
        List<Student> jichuban = new ArrayList<Student>();
        List<Student> jiuyeban = new ArrayList<Student>();

        school.put("就业班",jiuyeban);
        school.put("基础班",jichuban);
        jichuban.add(new Student("01","张三"));
        jichuban.add(new Student("02","李四"));
        jiuyeban.add(new Student("01","小明"));
        jiuyeban.add(new Student("02","小强"));


        // 获取每一个学生
        Set<Map.Entry<String, List<Student>>> entrySet = school.entrySet();
        for(Iterator<Map.Entry<String, List<Student>>> it = entrySet.iterator();it.hasNext();){
            Map.Entry<String, List<Student>> entry = it.next();
            List<Student> list = entry.getValue();  // 获取教师列表
            for(Iterator<Student> it1 = list.iterator();it1.hasNext();){
                System.out.println(it1.next());  // 获取每个学生
            }

        }
    }
}

class Student{
    private String id;
    private String name;

    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值