第一题
需求
目前有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;
}
}