最近刷题最容易踩坑的字符串 String 和 List 集合 题型,我把你写过的所有错题、错误原因、正确代码、底层原理一次性整理成一篇完整复盘博客。
全部是考试/作业高频题,看完直接避开90%的新手BUG。
一、List 一次性初始化赋值(新手简化写法)
问题:多次调用 add() 太繁琐,如何一次性存入多个元素?
错误写法:重复多行 add
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
正确简洁写法
// JDK8
ArrayList<Integer> list1 = new ArrayList<>(Arrays.asList(1,2,3,4,5));
// JDK9+ 更推荐
ArrayList<Integer> list1 = new ArrayList<>(List.of(1,2,3,4,5));
核心知识点:List.of() / Arrays.asList() 得到的是固定大小集合,必须外层 new ArrayList 才能后续增删。
二、字符串去除所有空格(常见逻辑误区)
需求:删除字符串全部空格(首尾+中间)
新手错误思路:只使用 trim() + 尝试修改原字符串
错误根源:
- String 不可变,不能循环中直接修改
- trim()只能去首尾空格,去不了中间空格
最简正确写法
public static String removeAllSpace(String str){
if(str == null) return "";
return str.replace(" ", "");
}
手动遍历原理版(理解用)
public static String removeAllSpace(String str){
if(str == null) return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c != ' '){
sb.append(c);
}
}
return sb.toString();
}
三、统计子串出现次数(substring 经典错题)
新手两大致命错误:
- substring(起始下标, 长度) ------ 第二个参数是结束下标,不是长度
- 字符串对比用 == 比较地址,不是内容
- 循环条件少等号,漏判最后一组
修正完整版
public static int subStringCount(String src,String sub){
if(sub == null || sub.length() == 0 || sub.length() > src.length()){
return 0;
}
int sum = 0;
int subLen = sub.length();
for (int i = 0; i <= src.length() - subLen; i++){
String temp = src.substring(i, i + subLen);
if (temp.equals(sub)){
sum++;
}
}
return sum;
}
四、字符串去重(保留第一次出现的字符)
你的原代码BUG:
- 先 append 再判断,永远去重失败
- contains 不能直接传 char
- 返回值类型不匹配,需要 toString()
正确代码
public static String removeDuplicateChar(String str){
StringBuilder s1 = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
// 没有该字符才追加
if(s1.toString().indexOf(c) == -1){
s1.append(c);
}
}
return s1.toString();
}
核心逻辑:先判断、后添加!
五、List 遍历删除元素(并发修改异常经典题)
错误代码现象 :增强 for 循环中 list.remove() 直接报错 ConcurrentModificationException
错误原因:增强for基于迭代器,遍历中修改集合结构会触发校验异常
最优三种写法
-
Java8 最简写法(推荐)
public static void removeBiggerThan10(List
list){
list.removeIf(s -> s > 10);
} -
迭代器写法(考试标准)
public static void removeBiggerThan10(List
list){
Iteratorit = list.iterator();
while(it.hasNext()){
Integer s = it.next();
if(s > 10){
it.remove();
}
}
}
六、偶数放前面、奇数放后面(原地排序高频错题)
你的原代码BUG:
- remove 之后没有临时变量,元素丢失,拿到错误值
- 删除元素后 i 继续++,漏掉元素
- 直接插入导致元素重复、下标错乱
稳妥满分写法(新建集合,零BUG)
public static List<Integer> evenFirst(List<Integer> list){
List<Integer> newList = new ArrayList<>();
// 先存偶数
for(Integer num : list){
if(num % 2 == 0){
newList.add(num);
}
}
// 再存奇数
for(Integer num : list){
if(num % 2 != 0){
newList.add(num);
}
}
return newList;
}
七、List 获取最小值(逻辑完全跑偏错题)
你的原代码问题:双层循环累加数值,完全不是求最小值
正确求最小值标准写法
public static int getMin(List<Integer> list){
if(list == null || list.isEmpty()){
throw new RuntimeException("集合为空");
}
int min = list.get(0);
for (Integer num : list){
if(num < min){
min = num;
}
}
return min;
}
八、字符串下标常用方法(必背对应关系)
-
charAt(下标):根据下标拿字符
-
indexOf(字符/子串):根据内容拿下标,找不到返回 -1
-
lastIndexOf():从后往前找下标
九、全篇核心避坑总结(考前必看)
- String 不可变,所有修改都要新字符串 / StringBuilder
- 字符串比较内容必须用 equals,坚决不用 ==
- substring 第二个参数是结束索引,不是长度
- 增强 for 循环不能增删集合,必报并发修改异常
- 集合删除元素后下标会前移,普通for循环必须手动控制i
- 去重、判断类逻辑:先判断,再操作