Java实现去重保留空格功能时遇数组越界异常求助
数组去重(保留空格)实现遇IndexOutOfBoundsException问题
需求
实现数组去重功能,但保留空格(" ")。尝试不通过复制的方式实现,多次尝试均触发IndexOutOfBoundsException异常。
尝试的方法
第一种方法
思路:接收输入,调用函数创建ArrayList,遍历字符串将每个字符加入列表,再次遍历列表,将每个字符与首个索引的字符比较,若相等则从列表中移除。
问题代码片段:
if(character.get(i).equals(character.get(k))) { character.remove(arr.charAt(i)); }
完整代码:
import java.util.*; public class NoRepeats { public static void main(String args[]) { System.out.print("Please enter a phrase: "); Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); char[] characters = chars(input); } public static char[] chars(String arr) { ArrayList<Character> character = new ArrayList<Character>(); for(int i = 0; i<arr.length();i++) { character.add(arr.charAt(i)); for(int k = 1; k<arr.length();k++) { if(character.get(i).equals(character.get(k))) { character.remove(arr.charAt(i)); } } } System.out.print(character); return null; } }
报错信息:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266) at java.base/java.util.Objects.checkIndex(Objects.java:359) at java.base/java.util.ArrayList.get(ArrayList.java:427) at NoRepeats.chars(NoRepeats.java:20) at NoRepeats.main(NoRepeats.java:10)
第二种方法
核心代码片段:
for(int k = 0;k < characters.length;k++) { if(characters[i]==characters[k]) { System.out.print(character); character.remove(characters[i]); }
完整代码:
import java.util.*; public class NoRepeats { public static void main(String args[]) { System.out.print("Please enter a phrase: "); Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); //receive input char[] characters = chars(input); //call function } public static char[] chars(String arr) { ArrayList<Character> character = new ArrayList<Character>(); //create an empty arraylist char[] characters = arr.toCharArray(); for(int j = 0; j<characters.length;j++) { character.add(characters[j]); } for(int i = 0; i<characters.length;i++) { /*traverse through the orignal array adding a character to the empty array list each time*/ for(int k = 0;k < characters.length;k++) { if(characters[i]==characters[k]) { System.out.print(character); character.remove(characters[i]); } } } return null; } }
报错信息:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 118 out of bounds for length 2 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266) at java.base/java.util.Objects.checkIndex(Objects.java:359) at java.base/java.util.ArrayList.remove(ArrayList.java:504) at NoRepeats.chars(NoRepeats.java:33) at NoRepeats.main(NoRepeats.java:11)
预期输入输出
- 预期输入:
“And I think to myself: what a wonderful world!”
- 预期输出:
And I thk o myself: w ru !
问题原因分析
第一种方法:
- 遍历字符串时,每次添加字符后立刻用
k遍历原字符串全长度,但此时ArrayList的长度还未达到原字符串长度,character.get(k)会访问超出列表当前长度的索引,触发越界异常。 character.remove(arr.charAt(i))是按元素值删除,而非按索引,当列表中有多个相同元素时会删除第一个匹配项,逻辑错误且易导致后续索引混乱。
- 遍历字符串时,每次添加字符后立刻用
第二种方法:
character.remove(characters[i])按值删除,当列表中该字符已被删除后,再次调用会尝试删除不存在的元素;同时循环仍用原数组长度遍历,列表缩短后操作会超出范围。- 嵌套循环逻辑错误,会重复多次删除同一个字符,导致列表快速缩短,后续操作越界。
解决方案
要实现保留空格的去重,核心是记录已出现的非空格字符,遍历原字符串时只保留首次出现的非空格字符,空格全部保留。实现代码如下:
import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class NoRepeats { public static void main(String[] args) { System.out.print("Please enter a phrase: "); Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); String result = removeDuplicatesKeepSpaces(input); System.out.println(result); } public static String removeDuplicatesKeepSpaces(String input) { Set<Character> seenChars = new HashSet<>(); StringBuilder sb = new StringBuilder(); for (char c : input.toCharArray()) { // 空格直接保留,无需去重 if (c == ' ') { sb.append(c); } else { // 非空格字符,仅保留首次出现的 if (!seenChars.contains(c)) { seenChars.add(c); sb.append(c); } } } return sb.toString(); } }
代码说明
- 使用
HashSet记录已处理的非空格字符,判断重复的时间复杂度为O(1)。 - 使用
StringBuilder高效构建结果字符串,避免频繁字符串拼接的性能损耗。 - 遍历原字符串时,空格直接追加;非空格字符仅在首次出现时追加,同时加入
HashSet标记为已出现。
测试预期输入时,输出与预期一致:And I thk o myself: w ru !
内容的提问来源于stack exchange,提问作者Sinazo Toyi
相关产品推荐
相关产品推荐

