Java基础09-集合框架—双列集合

九、集合框架—双列集合

1、Map集合

Map集合称为双列集合,格式: {key1=value1 , key2=value2 , key3=value3…,一次需要存一 对数据做为一 个元素。

Map集合的每个元素"key=value" 称为一个键值对/键值对对象/一个Entry对象, Map集合也被叫做"键值对集合”。

Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的, 每-个键只能找到自己对应的值。

在这里插入图片描述

Map集合系列特点:

Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的。

HashMap (由键决定特点) : 无序、不重复、无索引; (用的最多)

LinkedHashMap ( 由键决定特点) :有序、不重复、无索引。

TreeMap(由键决定特点):按照键按大小排序,默认升序排序,可排序,不重复、无索引

1.1 Map集合提供的常用方法

Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的。

方法名称说明
public V put( K key , V value )添加元素
public int size( )获取集合的大小
public void clear( )清空集合
public boolean isEmpty()判断集合是否为空,为空返回:true,反之为:false
public V get ( Object key )根据键获取对应值
public V remove( Object key )根据键删除整个元素
public boolean containsKey(Object key)判断是否包含某个键
public boolean containsValue( Object value )判断是否包含某个值
public Set keySet( )获取全部键的集合,返回一个Set集合
public Collection values( )获取Map集合的全部值,返回一个Collection集合
public void putAll( Map map )将Map集合的所有元素添加到,另一个集合中
public class MapDemo {
    public static void main(String[] args) {

        //创建一个 HashMap对象:无序、不重复、无索引的
        //Map<键类型,值类型>
        Map<String,Integer> map=new HashMap<>();
        //添加数据
        map.put("手机",1999);
        map.put("电视",1999);
        map.put("手表",399);
        map.put("电脑",5500);
        System.out.println(map);  //{手表=399, 电脑=5500, 手机=1999, 电视=1999}

        //判断map双列集合是否为空
        System.out.println(map.isEmpty());  //false
        //获取map的长度
        System.out.println(map.size());  //4

        //获取双列表的键值,返回类型为Set集合
        Set<String> key=map.keySet();
        System.out.println(key);  //[手表, 电脑, 手机, 电视]

        //获取双列表的所有的值,返回值类型为Collection
        Collection<Integer> list=map.values();
        System.out.println(list);  //[399, 5500, 1999, 1999]

        //根据键来获取值
        System.out.println(map.get("电脑"));  //5500

        //判断双列表中是否包含对应的键
        System.out.println(map.containsKey("手表")); //true

        //判断双列表中是否包含对应的值
        System.out.println(map.containsValue(399));//true

        //创建一新的map集合
        Map<String,Integer> map1=new HashMap<>();
        map1.put("冰箱",2999);
        //将map中所有的元素添加到map1中
        System.out.println(map1);  //{冰箱=2999}
        map1.putAll(map);
        System.out.println(map1);  //{手表=399, 电脑=5500, 手机=1999, 冰箱=2999, 电视=1999}

        //清空map中的所有元素
        map.clear();
        System.out.println(map); //{}

    }
}
1.2、Map集合的遍历方式

方式一:键找值(先获取Map集合全部的键,再通过遍历键来找值 )

方式二:键值对(把“键值对“看成一个整体进行遍历(难度较大))

方式三:Lambda(jDK 1.8开始之后的新技术(非常的简单))

public class MapDemo02 {
    public static void main(String[] args) {

      Map<String,Integer>  map =new HashMap<>();
        //添加数据
        map.put("手机",1999);
        map.put("电视",1999);
        map.put("手表",399);
        map.put("电脑",5500);
        System.out.println(map);  //{手表=399, 电脑=5500, 手机=1999, 电视=1999}

        //方式一:通过键找到值的方式来遍历
        //第一步:通过KeySet方法来获取所有的键
        Set<String> keys=map.keySet();
        //第二步,通过增强for循环获取键,并通过get方法来遍历值
        for (String key : keys) {
            //获取值
            int price=map.get(key);
            System.out.println(key+"------"+price);
        }


        //方式二:调用Map集合提供entrySet方法,把Map 集合转换成键值对类型的Set集合
        //第一步:将Map集合转换为Set集合
        Set<Map.Entry<String,Integer>> entries=map.entrySet();
        System.out.println(entries);  //[手表=399, 电脑=5500, 手机=1999, 电视=1999]
        //第二步:通过增强for循环,遍历set集合
        for (Map.Entry<String, Integer> entry : entries) {
            //提供Entry提供的getKey和getValue来获取对应的键和值
             String key=entry.getKey();
             Integer value=entry.getValue();
            System.out.println(key+"-----"+value);
        }


        //方式三:通过Lambda方式遍历Map集合(k和v是随便定义的变量)
        map.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String k, Integer v) {
                System.out.println(k+"----"+v);
            }
        });
         //缩写方式
        map.forEach((k,v)->{
            System.out.println(k+"----"+v);
        });
    }
}

案例:Map集合的案例-统计投票人数

需求:某个班级80名学生,现在需要组织秋游活动,班长提供了四个景点依次是(A、B、C、D) ,每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。

分析:

①将80个学生选择的数据拿到程序中去, [A,A,B,A,B, C,D,…]
②准备一个Map集合用于存储统计的结果,Map<String, Integer>, 键是景点,值代表投票数量。
③遍历80个学生选择的景点,每遍历一一个景点,就看Map集合中是否存在该景点,不存在存入“景点=1“存在则其对应值+1,

public class MapCount {
    public static void main(String[] args) {
        //调用学生进行投票(传入学生数量,返回值为学生投完票的集合)
        List<String> list=studentVote(80);
        //学生随机投票的的结果
        System.out.println(list);  //[C, A, D, B, A, A, C, C, C, B,...]
        
        //对投票进行统计处理(传入list集合,返回值为一个map集合)
        Map<String,Integer> map=studentVoteCount(list);
        //展示随机投票进行统计后的结果
        System.out.println(map);  //{A=19, B=17, C=20, D=24}
    }


    //通过studentVote方法获取学生的投票信息
    public static List<String> studentVote(int count){
        //创建一个List集合,用来装学生投的票
        List<String> list=new ArrayList<>();

        //创建一个随机数,将用来产生count个随机投票
        Random random=new Random();
        for (int i = 0; i < count; i++) {
           //通过随机数来产生65-68的整数(分别是A-D的AscII码)
           int option= random.nextInt(4)+65;

           //将数值型类型转换为String类型的数据(先要将数值转换为char类型的A)
            //也可以:String  vote=(char)option+"";
            String  vote=String.valueOf((char)option);

           //将产生的随机数添加到List集合中去
            list.add(vote);
        }

      return list;
    }



    //统计学生们投票的票数
    public static Map<String,Integer>  studentVoteCount(List<String> list){
        //创建一个Map集合,用来统计学生对各个景区的投票数
        Map<String,Integer> map=new HashMap<>();
        //通过遍历list集合,获取到各个投票,进行统计
        for (String vote : list) {
            //判断map集合是否有vote对应的key,有就把原来的value+1,并把原来的替换掉(因为HashMap的键不能重复)
            //没有就添加对应的key和投票数量1
            if(map.containsKey(vote)){
                int value=map.get(vote)+1;
                map.put(vote,value);
            }else {
                map.put(vote,1);
            }
        }

        return map;
    }

}

2、HashMap 集合

特点:HashMap (由键决定特点) :无序、不重复、无索引; (用的最多 )

原理:HashMap跟HashSet的底层原理是一模一 样的,都是基于哈希表实现的。

实际上:原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。

jDK8之前,哈希表=数组+链表

jDK8开始,哈希表=数组+链表+红黑树

哈希表是一种增删改查数据,性能都较好的数据结构,所有HashMap也是。

注意:

HashMap的键依赖hashCode方法和equals方法保证键的唯一。

如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。

操作方法:在实体类中,右击》Generate》equals() and hashCode()》一直next

3、LinkedHashMap 集合

特点:LinkedHashMap ( 由键决定特点) :有序、不重复、无索引。

原理:底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表 的机制记录元素顺序(保证有序)。

实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap.

通过双链表机制的,首指针和尾指针来记录元素顺序。

public class LinkedHashMapDemo {
    public static void main(String[] args) {
        Map<String,String> map=new LinkedHashMap<>();
        map.put("小明","篮球");
        map.put("小天","足球");
        map.put("小花","排球");
        map.put("小刚","篮球");
        System.out.println(map);  //输出结果是有序的:{小明=篮球, 小天=足球, 小花=排球, 小刚=篮球}
    } 
}

4、TreeMap 集合

特点:TreeMap ( 由键决定特点) :按照大小默认升序排序、不重复、无索引。

原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。

TreeMap集合同样也支持两种方式来指定排序规则

方式一:让类实现Comparable接口,重写compareTo()方法比较规则。

方式二:TreeMap集合有 一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则。

5、补充知识-集合的嵌套

定义:指的是集合中的元素又是一个集合。

5.1 Map集合案例-省和市

需求:要求在程序中记住如下省份和其对应的城市信息,记录成功后,要求可以查询出湖北省的城市信息。

分析:定义一个Map集合,键用表示省份名称,值表示城市名称,注意:城市会有多个。

public class Test {
    public static void main(String[] args) {

        //1、定义一个Map集合存储全部的省份信息,和其对应的城市信息。
        Map<String, List<String>> map=new HashMap<>();

        //2、创建一个List集合将城市信息放到集合中
        List<String> cities1=new ArrayList<>();
        //2.1、将城市信息存入到list集合中
        Collections.addAll(cities1,"南京市", "扬州市", "苏州市","无锡市", "常州市");
        //3、将城市信息存入对应的省份Map集合中
         map.put("江苏省",cities1);

        //2、创建一个List集合将城市信息放到集合中
        List<String> cities2=new ArrayList<>();
        //2.1、将城市信息存入到list集合中
        Collections.addAll(cities2,"武汉市", "孝感市", "十堰市","宜昌市", "鄂州市");
        //3、将城市信息存入对应的省份Map集合中
        map.put("湖北省",cities2);

        //2、创建一个List集合将城市信息放到集合中
        List<String> cities3=new ArrayList<>();
        //2.1、将城市信息存入到list集合中
        Collections.addAll(cities3,"石家庄市","唐山市","邢台市","保定市","张家口市");
        //3、将城市信息存入对应的省份Map集合中
        map.put("河北省",cities3);

        System.out.println(map);
        //{江苏省=[南京市, 扬州市, 苏州市, 无锡市, 常州市], 湖北省=[武汉市, 孝感市, 十堰市, 宜昌市, 鄂州市], 河北省=[石家庄市, 唐山市, 邢台市, 保定市, 张家口市]}


        //查询湖北省的各个城市
        List<String> hb=map.get("湖北省");
        System.out.println(hb); //[武汉市, 孝感市, 十堰市, 宜昌市, 鄂州市]
        
        
        //遍历整个map
        map.forEach((k,v)->{
            System.out.println(k+"----"+v);
        });
          /*江苏省----[南京市, 扬州市, 苏州市, 无锡市, 常州市]
            湖北省----[武汉市, 孝感市, 十堰市, 宜昌市, 鄂州市]
            河北省----[石家庄市, 唐山市, 邢台市, 保定市, 张家口市]*/
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值