27-集合进阶综合案例

集合进阶综合案例

一、小案例:自动点名器

1、点名器:简单的随机点名
需求
  • 班级里有N个学生,实现随机点名器。

测试类
package com.app.demo32_sets_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class Test1 {
    public static void main(String[] args) {
        /*
            案例:自动点名器1
            需求:
                班级里有N个学生,实现随机点名器。
         */
        // 1.创建集合,用于存储学生姓名
        ArrayList<String> list = new ArrayList<>();
        // 2.添加数据到集合中
        Collections.addAll(list, "范闲", "令狐冲", "杨过", "杨康", "王重阳", "甄姬", "小乔", "大乔", "袁隆平");
        // 3.随机点名
        // 方式1:
        Random rd = new Random();            // 创建随机数对象
        int index = rd.nextInt(list.size()); // 生成一个随机索引
        String name = list.get(index);       // 随机点一名学生
        System.out.println("随机点到了" + name + "同学~");

        System.out.println("--------------");

        // 方式2:
        // 打乱
        Collections.shuffle(list);
        String name2 = list.get(0);
        System.out.println("随机点到了" + name2 + "同学~");
    }
}

测试结果
随机点到了范闲同学~
--------------
随机点到了甄姬同学~

Process finished with exit code 0



2、点名器:带概率的随机点名
需求
  • 班级里有N个学生,要求70%的概率随机到男生、30%的概率随机到女生。

分析
  • 不要想得太复杂:
    1. 我们定义一个概率集合,存入7个1,存入3个0,7个1表示70%概率,3个0表示30%概率
    2. 那么我们就可以定义两个集合分别用于存储男生和女生的姓名
    3. 当随机到1的时候,就去男生的集合中随机一个名字出来
    4. 当随机到0的时候,就去女生的集合中随机一个名字出来
  • 这样就可以解决了概率的问题了

测试类
package com.app.demo32_sets_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class Test2 {
    public static void main(String[] args) {
        /*
            小案例:自动点名器2
            需求:
                班级里有N个学生,要求70%的概率随机到男生、30%的概率随机到女生。

            男生名字:"关羽", "范闲", "诸葛亮", "孙悟空", "马云", "宋合泛", "呼延烈"
            女生名字:"波赛西", "小舞", "朱竹清", "甄姬", "蔡文姬"
         */
        // 1.定义一个概率集合
        ArrayList<Integer> probableList = new ArrayList<>();
        // 2.存入7个1表示70%的概率,存入3个0表示30%的概率
        Collections.addAll(probableList, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
        // 3.将集合中所有的元素打乱
        Collections.shuffle(probableList);
        // 4.随机一个1或0
        Random rd = new Random();
        int index = rd.nextInt(probableList.size());
        int number = probableList.get(index);
        // System.out.println(number);

        // 5.创建两个集合分别用于存储男生、女生的名字
        ArrayList<String> boyList = new ArrayList<>();
        ArrayList<String> girlList = new ArrayList<>();

        // 6.分别往男生、女生的集合中添加名字
        Collections.addAll(boyList, "关羽", "范闲", "诸葛亮", "孙悟空", "马云", "宋合泛", "呼延烈");
        Collections.addAll(girlList, "波赛西", "小舞", "朱竹清", "甄姬", "蔡文姬");

        // 7.随机点名
        // 判断number是否为1
        if (number == 1) {
            // 是,则去男生的集合中随机一个名字出来
            int boyIndex = rd.nextInt(boyList.size());
            String boyName = boyList.get(boyIndex);
            System.out.println("随机点到了" + boyName + "同学~");
        } else {
            // 否,则去女生的集合中随机一个名字出来
            int girlIndex = rd.nextInt(girlList.size());
            String girlName = girlList.get(girlIndex);
            System.out.println("随机点到了" + girlName + "同学~");
        }
    }
}

测试结果
随机点到了呼延烈同学~

Process finished with exit code 0



3、点名器:不重复的随机点名
需求
  • 班级里有N个学生,要求被点过的学生不会再被点到,但是如果班级中所有的学生都点完了,需要重新开启第二轮点名。

分析
  • 先把随机点名写出来,然后再一步一步完善。
  • 再实现被点过的学生不会再被点到。
  • 再实现但是如果班级中所有的学生都点完了。
  • 最后实现重新开启第二轮点名。

测试类
package com.app.demo32_sets_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class Test3 {
    public static void main(String[] args) {
        /*
            点名器:不重复的随机点名
            需求
                班级里有N个学生,要求被点过的学生不会再被点到,
                但是如果班级中所有的学生都点完了,需要重新开启第二轮点名。

                "关羽", "范闲", "诸葛亮", "孙悟空", "马云", "宋合泛", "呼延烈", "波赛西", "小舞", "朱竹清"
         */
        // 1.定义集合,用于存储学生名字
        ArrayList<String> nameList = new ArrayList<>();

        // 2.添加名字到集合中
        Collections.addAll(nameList, "关羽", "范闲", "诸葛亮", "孙悟空", "马云", "宋合泛",
                "呼延烈", "波赛西", "小舞", "朱竹清");

        // 3.创建一个临时的集合,用于将被点过的学生名字存储起来
        ArrayList<String> tempList = new ArrayList<>();

        // 4.随机点名
        // 创建随机数对象
        Random rd = new Random();
        // 外循环:表示轮数
        for (int i = 1; i <= 3; i++) {
            System.out.println("=======第" + i + "轮随机点名开始=======");
            // 为了避免每循环1次,集合长度-1的情况,先在内循环外将集合长度获取出来
            int size = nameList.size();
            // 内循环:每轮中随机循环抽取的过程
            for (int j = 0; j < size; j++) {
                // 生成一个随机索引
                int index = rd.nextInt(nameList.size());
                // 随机点一个名字出来,并将点到的学生删除掉,避免下次再点到
                String name = nameList.remove(index);
                // 将被点过的学生名字存储到临时集合中
                tempList.add(name);
                System.out.println(name);
            }

            // 5.循环结束,此时nameList集合已经空了,tempList已经将所有被点过的学生名字都存储起来了
            // 每轮随机点名结束后,需要将tempList集合中的所有名字 重新给到 nameList集合
            nameList.addAll(tempList);
            // 然后将tempList集合清空,这样下一轮点名后,里面的数据才不会重复
            tempList.clear();
        }
    }
}

测试结果
=======第1轮随机点名开始=======
小舞
范闲
宋合泛
呼延烈
孙悟空
波赛西
关羽
诸葛亮
马云
朱竹清
=======第2轮随机点名开始=======
朱竹清
范闲
诸葛亮
马云
关羽
波赛西
小舞
孙悟空
宋合泛
呼延烈
=======第3轮随机点名开始=======
孙悟空
呼延烈
范闲
马云
小舞
关羽
朱竹清
宋合泛
波赛西
诸葛亮

Process finished with exit code 0



二、小案例:省和市(集合嵌套)

需求
  • 需要一个Map集合,键用省份名称(province),值用市(city),但是市会有多个。

  • 添加完毕后,遍历结果格式如下:

    江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
    湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
    河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市
    

测试类
package com.app.demo32_sets_test;

import java.util.*;

public class Test4 {
    public static void main(String[] args) {
        /*
            案例:省和市(集合嵌套)
            需求:
                需要一个Map集合,键用省份名称(province),值用市(city),但是市会有多个。
                添加完毕后,遍历结果格式如下:
                    江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
                    湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
                    河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市
         */
        // 1.创建Map集合,键:省份名称,值:市(集合:多个城市)
        HashMap<String, ArrayList<String>> hm = new HashMap<>();

        // 2.创建单列集合,用于存储多个城市
        ArrayList<String> city1 = new ArrayList<>();
        // 添加城市
        Collections.addAll(city1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");

        ArrayList<String> city2 = new ArrayList<>();
        Collections.addAll(city2, "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市");

        ArrayList<String> city3 = new ArrayList<>();
        Collections.addAll(city3, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");

        // 3.往Map集合中添加各个省份与各个省份的城市集合
        hm.put("江苏省", city1);
        hm.put("湖北省", city2);
        hm.put("河北省", city3);

        // 按照指定的格式拼接各个省份与各个省份的每个市
        // 方式1
        // 4.外循环:遍历Map集合,依次得到每个省份和市的集合(得到所有的键值对)
        hm.forEach((province, citys) -> {
            // 获取当前省份的所有市集合的长度
            int size = citys.size();
            // 先拼接当前省份(键对象)
            System.out.print(province + " = ");
            // 内循环:遍历当前省份的市集合,依次得到当前省份的每个市(得到所有的值对象)
            for (int i = 0; i < size; i++) {
                // 如果当前位置是集合中的末尾,则不拼接逗号,否则拼接逗号
                System.out.print(i == size - 1 ? citys.get(i) : citys.get(i) + ",");
            }
            // 循环结束!说明当前省份的所有城市已经拼接完成!输出个换行
            System.out.println();
        });

        System.out.println("---------------------------------------");

        // 方式2
        Set<Map.Entry<String, ArrayList<String>>> entries = hm.entrySet();
        entries.forEach(entry -> {
            // 获取所有的键对象
            String province = entry.getKey();
            // 获取所有的值对象的集合
            ArrayList<String> citys = entry.getValue();
            // 创建StringJoiner对象,用于按照指定的格式拼接各个省份与各个省份的所有城市
            // 参数一:分隔符——>用逗号隔开;参数二:开始符——>不需要拼接任何东西;参数三:结束符:不需要拼接任何东西
            StringJoiner sj = new StringJoiner(",", "", "");
            // 遍历值对象集合,依次获取每个城市,并且拼接每个城市
            citys.forEach(city -> sj.add(city));
            // 输出最终拼接结果
            System.out.println(province + " = " + sj);
        });
    }
}

测试结果
江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市
---------------------------------------
江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市

Process finished with exit code 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值