【Java的集合框架 Map 29】

总结Collection集合知识点

后缀名就是该集合所属的体系
前缀名就是该集合的数据结构

看到array:就要想到数组,就要想到查询快,有角标
看到link:就要想到链表,就要想到增删快,就要想到add get remove+first last的方法
看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode方法和equals方法
看到tree:就要想到二叉树,就要想到排序,就要想到两个接口comparaable,comparator

而且通常这些常用的集合容器都是不同步的

其实以上集合,核心的几点都是各自的方法,子类以及对应获取集合内的元素

list集合是有序,可重复;

set集合是无序,不可重复;

ArrayList,LinkedList 取不重复的元素,需要定义一个中间的集合,用contain来判断

HashSet,TreeSet 本身的集合就是不可重复的。

四个集合存基本数据类型的数据,迭代去元素时直接调用迭代Iterator接口即可

如果存的是引用类型的对象,迭代元素时都需要引用类重写hashcode(),equals(),toString()方法,

其中HashSet需要先判断元素的哈希值是否相同,然后在判断内容是否相同

TreeSet有两种方式进行比较重复判断的方式:1、让对象本身具备具备比较功能(comparable)

2、让几个具备比较功能(comparator)

==============================================

一、集合特点
Map<K,V>
类型参数:
K - 此映射所维护的键的类型
V - 映射值的类型

Map:一次添加一对元素。collection一次添加一个元素
Map也称双列集合,Collection集合称为单列集合。其实map集合中存储的就是键值对,map集合必须保证键的唯一性。

二、常用方法:
1、添加
 value put(key value):返回前一个和key关联的值,如果没有返回null
2、删除
void clear():清空map集合
value remove(key):根据指定的key翻出这个键值对
3、判断
boolean containsKey(key):
boolean containsValue(value)
boolean isEmpty()
4、获取
value get(key):通过键获取值,如果没有该键返回null。
当然可以通过返回null,来判断是否包含指定键

int size():获取键值对的个数。

-------> 代码演示方法<--------

package com.JavaStudy01.Map;

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

/**
 * @Author wufq
 * @Date 2020/8/7 10:01
 */
public class MapDemo01 {
    public static void main(String[] args){
        Map<Integer,String> map = new HashMap<Integer, String>();
        method(map);

    }

    private static void method(Map<Integer, String> map) {

        //增加
        System.out.println(map.put(2,"wangcai"));//null  -->相同键值,value值会被覆盖
        System.out.println(map.put(2,"xiaoqiang"));//wangcai  -->返回前一个和key关联的值
        map.put(7,"zhangsan");
        map.put(5,"lisi") ;

        System.out.println("添加后完整的map:"+map);

        //删除
        map.remove(5);

        //判断
        System.out.println(map.containsKey(5));//true

        //获取
        System.out.println(map.get(5));//lisi


        System.out.println(map);//{2=xiaoqiang}   -->key和value进行了关联
    }


}

5、重点:获取map中所有的元素

Map集合里面是没有迭代器的,那么要想获取集合里面的元素,思路是把map集合转换成Set集合
转换的两张方法:
第一种:使用keySet()方法 --> 获取map集合内所有的键存放到Set集合内,然后通过键取每一个值即可
第二种:使用entrySet()方法  --> 该方法将键和值作为映射对象存储到Set集合内,(entrySet()的映射对象是Map.entry<K,V>)然后通过Map.entry的getKey()和getValue
方法获取键和值

Map.Entry<K,V>是Map<K,V>的嵌套类

public static interface Map.Entry<K,V>
Map.EntrySet方法返回映射的Collection视图,其中的元素属于此类。获得映射项引用的唯一的方法是通过此collection视图的迭代器来实现。

方法:
boolean equals(Object o) ;比较指定对象与此项的相等性
K getKey();返回此项的键
V getValue():返回此项的值
V setValue():用指定的值替换此项对应的值

 

package com.JavaStudy01.Map;

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

/**
 * @Author wufq
 * @Date 2020/8/7 10:01
 * 获取集合内所有元素,思路是:通过map转换成set就可以迭代
 */
public class MapDemo01 {
    public static void main(String[] args){
        Map<Integer,String> map = new HashMap<Integer, String>();
        method_2(map);
        method_3(map);

    }
/* 第一种方法:keySet 原理:通过keySet方法获取map中所有键所在的set集合,然后通过set集合的迭代器获取每一个键,在对每一个键取其对应的值即可 */
    public static void method_2(Map<Integer, String> map) {

        map.put(7,"zhangsan");
        map.put(5,"lisi") ;
        map.put(8,"wangcai");
        map.put(1,"xiaoqiang") ;
        map.put(2,"wangwu");
        map.put(3,"zhaoliu") ;
  
        Set<Integer> keySet = map.keySet();
        Iterator<Integer> it=keySet.iterator();
        while (it.hasNext()){
            Integer key = it.next();
            String value = map.get(key);

            System.out.println(key+"::"+value);
        }
    }
 /* 第二种方法:entrySet() Map集合内的方法 原理:该方法将键和值的映射关系作为对象存储到set集合中,而这个映射关系就是Map.Entry类型(结婚照) */
    public static void method_3(Map<Integer, String> map) {
        map.put(7,"zhangsan");
        map.put(5,"lisi") ;
        map.put(8,"wangcai");
        map.put(1,"xiaoqiang") ;
        map.put(2,"wangwu");
        map.put(3,"zhaoliu") ;

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

}

第一种方法原理图:

 第二中方法原理图:

三、Map常用子类
|-- Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值
    |-- properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合
|-- HashMap:内部结构是哈希表,是不同步的
|-- TreeMap:内部结构是二叉树,不是同步的,可以对Map集合中的键进行排序 

1、HashMap存储自定义对象

需求:将学生对象和学生的归属地通过键与值存储到map集合中

---------->Students类<-----------

package com.JavaStudy01.Bean;

/**
 * @Author wufq
 * @Date 2020/8/7 16:43
 */
public class Students {
    private String name;
    private int age;

    public Students(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 int hashCode() {
        return name.hashCode()+age;
    }

    @Override
    public boolean equals(Object obj) {
        Students stu = (Students)obj;

        return this.name.equals(stu.name)&&this.age==stu.age;
    }
}

---------->HashMapDemo01<-----------

package com.JavaStudy01.Map;

import com.JavaStudy01.Bean.Students;

import java.util.HashMap;
import java.util.Iterator;

/**
 * @Author wufq
 * @Date 2020/8/7 16:29
 * 将学生对象和学生的归属地通过键与值存储到map集合中
 */
public class HashMapDemo01 {
    public static void main(String[] args){
        HashMap<Students,String> hm = new HashMap<Students,String>();

        hm.put(new Students("张三",22),"北京");
        hm.put(new Students("李四",23),"上海");
        hm.put(new Students("王五",29),"广州");
        hm.put(new Students("赵六",28),"深圳");
        hm.put(new Students("李四",23),"铁岭");

//        Set<Students> st = hm.keySet();
//        Iterator<Students> iter = st.iterator();

        //上面的写法可以直接写成这样
        Iterator<Students> iter = hm.keySet().iterator();
        while (iter.hasNext()){
            Students key = iter.next();
            String value = hm.get(key);
            System.out.println(key.getName()+":"+key.getAge()+"---"+value);
        }
    }

}

执行结果:
        张三:22---北京
        李四:23---铁岭
        赵六:28---深圳
        王五:29---广州
        李四:23---上海
        从上面的执行结果可以看出:李四的城市铁岭没有覆盖上海,所以这里面又涉及到一个知识点,hashMap的数据结构也是哈希表,所以需要重写hashCode和equals方法
重写以后执行结果:
       张三:22---北京
       赵六:28---深圳
       李四:23---铁岭
       王五:29---广州
2、TreeMap存储自定义对象

---------->ComparatorByName类继承Comparator接口,重写compare方法<----------------

 

package com.JavaStudy01.Bean;

import java.util.Comparator;

/**
 * @Author wufq
 * @Date 2020/8/6 14:37
 */
public class ComparatorByName implements Comparator<Students>{


    @Override
    public int compare(Students p1, Students p2) {

        int temp = p1.getName().compareTo(p2.getName());
        return temp==0?p1.getAge()-p2.getAge():temp;
    }


}

---------->TreeMapDemo01<----------------

package com.JavaStudy01.Map;

import com.JavaStudy01.Bean.ComparatorByName;
import com.JavaStudy01.Bean.Students;

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

/**
 * @Author wufq
 * @Date 2020/8/8 11:21
 */
public class TreeMapDemo01 {
    public static void main(String[] args){
        TreeMap<Students,String> tm = new TreeMap<>(new ComparatorByName());
        tm.put(new Students("张三",22),"北京");
        tm.put(new Students("李四",23),"上海");
        tm.put(new Students("王五",29),"广州");
        tm.put(new Students("赵六",28),"深圳");
        tm.put(new Students("李四",23),"铁岭");

        Iterator<Map.Entry<Students,String>> iter=tm.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry<Students,String> me=iter.next();
            Students stu = me.getKey();
            String value = me.getValue();

            System.out.println(stu.getName()+":"+stu.getAge()+value);
        }

    }
}
=====执行结果======
张三:22北京
李四:23铁岭
王五:29广州
赵六:28深圳

 3、linkedHashMap  有序排列(有序指的是集合内怎么存就怎么取)

package com.JavaStudy01.Map;

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

/**
 * @Author wufq
 * @Date 2020/8/8 15:11
 * LinkedHashMap有序排列(指的是怎么存怎么取)
 */
public class LinkedHashMapDemo01 {
    public static void main(String[] args){

        HashMap<Integer,String> hm = new LinkedHashMap<>();

        hm.put(2,"aaa");
        hm.put(7,"aba");
        hm.put(5,"aca");
        hm.put(1,"ada");

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

    }
}
=====执行结果=====
2::::aaa
7::::aba
5::::aca
1::::ada

 四、练习

练习一:"fghjvbfghfgh"获取该字符串中,每一个字母出现的次数,要求打印结果是;a(2)b(1)...;

package com.JavaStudy01.Map;

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

/**
 * @Author wufq
 * @Date 2020/8/8 15:27
 * 练习;
    "fghjvbfghfgh"获取该字符串中,每一个字母出现的次数,要求打印结果是;a(2)b(1)...;
   思路:
    分析结果字母和次数是存在映射关系的,而且这种关系是很多的并且是需要存储的,那么存储映射关系的有数组和map集合,
    这种映射关系是没有编号的,并且按照abc...这样进行排序的,所以使用TreeMap(TreeMap的特点是可以对键进行排序)

    步骤:
    1、把字符串转换成字符数组
    2、创建一个TreeMap集合存储字母和次数
    3、遍历数组,用每一个字母作为键去查Map集合的这个表
        |-- 如果键不存在,则值=1
        |-- 如果键存在,则值+1
    4、重新组装map集合,已使返回的结果形式为a(2)b(1)...
 */
public class MapTest01 {
    public static void main(String[] args){
        String str = "AAfghj  vdf!@g$hfghKK";

        String s = strToArray(str);

        System.out.println(s);
    }

    //字符串通过字符数组、集合转换成字符串
    public static String strToArray(String str) {

        //将字符串变成字符数组
        char[] chars = str.toCharArray();

        //定义一个集合
        Map<Character,Integer> map = new TreeMap<>();

        //遍历数组内的元素
        for(int i=0;i<chars.length;i++){
            //字符串内有空格和特殊符号,需要跳过后继续统计
            if(!(chars[i]>='a'&&chars[i]<='z'||chars[i]>='A'&&chars[i]<='Z')) {
                continue;
            }
            //通过数组的index去获取集合内的值
            Integer value = map.get(chars[i]);

            /*
            /判断是否为空的第一种写法<--------

            int count=0;
            if(value!=null){
                count=value;
            }
            count++;
            map.put(chars[i],count); */

            /*
            /判断是否为空的第二种写法<--------
            */
            int count = 1;
            if(value!=null){
                count = value+1;
            }
            map.put(chars[i],count);

            /*
            /判断值是否为空第三种写法<---------

            if(value==null){
                map.put(chars[i],1);
            }else {
                map.put(chars[i],value+1);
            }
            */
        }
        return mapToString(map);
    }

    //把集合内的对象转换成这样的格式:a(2)b(1)...
    private static String mapToString(Map<Character, Integer> map) {

        Iterator<Map.Entry<Character,Integer>> iter = map.entrySet().iterator();
        StringBuilder sb = new StringBuilder();

        while (iter.hasNext()){
            Map.Entry<Character,Integer> me =iter.next();
            Character key = me.getKey();
            Integer value = me.getValue();

            sb.append(key+"("+value+")");
        }
        return sb.toString();
    }
}
====执行结果====
A(2)K(2)d(1)f(3)g(3)h(3)j(1)v(1)

练习二:

package com.JavaStudy01.Map;

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

/**
 * @Author wufq
 * @Date 2020/8/8 18:38
 * Map在有映射时,优先使用
 *
 * 在查表法中优先使用
 */
public class MapTest02 {
    public static void main(String[] args){

        String weeks = getWeek(3);
        System.out.println(weeks);

        String weeks1=getMapWeeks(weeks);
        System.out.println(weeks1);

    }

    //通过map集合里面的key(即:礼拜一...)去查value(Mon...)
    public static String getMapWeeks(String week) {
        Map<String,String> map = new HashMap<>();

        map.put("礼拜一","Mon");
        map.put("礼拜二","Tus");
        map.put("礼拜三","Wen");
        map.put("礼拜四","Fou");
        map.put("礼拜五","Fir");
        map.put("礼拜六","Str");
        map.put("礼拜日","Sun");

        return map.get(week);
    }


    //通过输入数字,查找礼拜一,二...
    public static String getWeek(int week) {

        if(week<1 || week>7){
            throw new RuntimeException("输入错误,请重新输入");
        }
        String[] weeks = {"","礼拜一","礼拜二","礼拜三","礼拜四","礼拜五","礼拜六","礼拜日"};

        return weeks[week];
    }
}
====执行结果====
礼拜三
Wen

 

posted @ 2020-08-07 11:17  尘封~~  阅读(107)  评论(0编辑  收藏  举报