【Java实战】综合例题练习,大一学生思路漏洞辨析

第一题

需求
目前有100名囚犯,每个囚犯的编号是1-200之间的随机数。现在要求依次随机生成100名囚犯的编号(要求这些囚犯的编号是不能重复的),然后让他们依次站成一排。
(注:位置是从1开始计数的),接下来,国王命令手下先干掉全部奇数位置处的人。剩下的人,又从新按位置1开始,再次干掉全部奇数位置处的人,依此类推,直到最后剩下一个人为止,剩下的这个人为幸存者。

具体功能点的要求如下
请输出幸存者的编号,以及他第一次所占的位置值是多少。
在这里插入图片描述

错误原因

动态数组大小改变与固定索引循环的冲突:

代码使用 for (int i = 1; i <= 100; i++) 来遍历并删除元素。在 ArrayList 中删除元素时,数组的大小会动态变化。例如,当删除索引 i 处的元素后,原本索引 i + 1 处的元素会移动到索引 i 位置。
但是循环仍然按照固定的 i 自增逻辑继续进行,这就导致当 i 达到一定值后,会超出 ArrayList 实际的大小范围,从而抛出 IndexOutOfBoundsException 异常。

循环条件与实际元素删除逻辑不匹配:

while(prisoner.size()!= 1) 这个循环条件的本意是持续删除元素直到只剩下一个元素。
然而,由于内部 for 循环中删除元素的逻辑错误,每次删除操作没有正确处理索引变化,导致循环可能无法正确减少列表中的元素数量。

下一步
使用迭代器
在这里插入图片描述
错误原因
使用 Iterator 时直接通过 prisoner 进行删除操作:

当使用 Iterator 遍历集合时,不应该直接通过集合对象(这里是 prisoner)调用 remove 方法。应该使用 Iterator 本身的 remove 方法。这是因为直接通过集合删除元素会破坏 Iterator 的内部状态,可能导致意外行为。

改正版本

package kaoshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

public class demo1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
    Random rand=new Random();
    ArrayList prisoner=new ArrayList<>();
    for(int i=1;i<=100;i++) {
    int nump=rand.nextInt(200)+1;
    prisoner.add(nump);
    }
    while(prisoner.size()!=1) {
    Iterator<Integer> iterator=prisoner.iterator();
    int index=1;
    while(iterator.hasNext()) {
    	iterator.next();
    	if(index%2!=0) {
    		iterator.remove();	
        }
    	index++;
    }
    }
    System.out.println(prisoner);
	}
  
	}
	


但未考虑编号不能重复

package kaoshi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

public class demo1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
    Random rand=new Random();
    ArrayList prisoner=new ArrayList<>();
    for(int i=1;i<=100;i++) {
    int nump=rand.nextInt(200)+1;
    if(prisoner.contains(nump)) {
    i--;	
    }else {
    prisoner.add(nump);
    }
    }
    
    while(prisoner.size()!=1) {
    Iterator<Integer> iterator=prisoner.iterator();
    int index=1;
    while(iterator.hasNext()) {
    	iterator.next();
    	if(index%2!=0) {
    		iterator.remove();	
        }
    	index++;
    }
    }
    System.out.println(prisoner);
	}
	}

第二题
需求
User 实体类
包含如下属性
• private Long id;
• private String gender;
• private LocalDate birthday;

• 注意需要提供 set和get方法,以及toString方法
• 新建测试类,类中 main 方法,在方法中完成如下业务逻辑:
• 业务一:
• 有如下字符串,里面包含多个用户信息数据,现在需要你解析这个字符串,获取里面的用户数据,并封装到User对象中
• 多个User对象在添加到List 集合中

业务二:
• 遍历上面获取的List 集合,统计里面每个名字出现的次数。
• 封装到Map<String,Integer>集合中,集合的key就是名字,value就是名字出现的次数。

package kaoshi;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class demo2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	String userStrs="10001:张三:男:1990-01-01#1002:李四:男:1989-01-09#1003:王五:男:1899-09-15";
	ArrayList users=new ArrayList<>();
	String[] UserArray=userStrs.split("#");
	for(String userStr:UserArray) {
		User user=new User();
		String[] userData=userStr.split(":");
		user.setId(Long.valueOf(userData[0]));
		user.setName(userData[1]);
		user.setGender(userData[2]);
		user.setBirthday(LocalDate.parse(userData[3]));
		users.add(user);
	}
	System.out.println(users);
	System.out.println("------------------------------------");
	
	  Map<String, Integer> nameCountMap = countNames(users);

      // 打印结果
      for (Map.Entry<String, Integer> entry : nameCountMap.entrySet()) {
          System.out.println(entry.getKey() + ": " + entry.getValue() + " 次");
      }
	    }
	public static Map<String, Integer> countNames(List<User> userList) {
	        Map<String, Integer> nameCountMap = new HashMap<>();
	        for (User user : userList) {
	            String name = user.getName();
	            // 如果名字已经在Map中,将其计数加1
	            if (nameCountMap.containsKey(name)) {
	                nameCountMap.put(name, nameCountMap.get(name) + 1);
	            } else {
	                // 如果名字不在Map中,将其加入并设置计数为1
	                nameCountMap.put(name, 1);
	            }
	        }
	        return nameCountMap;
	}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值