任务:有一个字符串,您需要从中删除所有以“a”开头的单词并将其放入一个数组中。
我决定做什么:
- 将所有标点符号、空白符号和双空格替换为一个空格,以便我可以使用
.split() - 实际上我使用了它
.split(" ")并立即将其结果放入 ArrayList - 然后我想迭代这个集合并打印我需要的,并删除不需要的,但我遇到了一个异常:
线程“main”中的异常 java.util.ConcurrentModificationException
(后来我意识到我只能删除它,并且不会出现错误,但我已经想以不同的方式解决它)
- 我用谷歌搜索-->遇到了它
Iterator,现在我想通过它来解决它以便更好地理解Java Iterator我在此基础上创建了它ArrayList- 然后我想while遍历迭代器,如果第一个字符是"a",则打印该单词 - 否则我从迭代器中删除该单词。
但这就是问题开始的地方:
if ("a".equals(String.valueOf(a.charAt(0)))) {这是哪里a:
String a = String.valueOf(iterator.next());
回来了false,不知道为什么……
与此同时,我决定在这个循环之后显示迭代器的所有元素,但我没有显示任何一个,这原则上是合乎逻辑的,因为条件返回 false,所有内容都被删除了,但随后,为了好玩,我输入的索引不是 0 ,而是 1,我在循环中得到了迭代器的所有单词,但是在循环中我仍然没有得到一个单词,好像上一个循环已经将它们全部删除了,这不可能发生,因为事实是真的。12
import java.util.Arrays;
import java.util.Iterator;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
test1();
}
public static void test1() {
String text = "aajiwi aiwefhfhwe wagw, gerhbdf - aiwrhgwbdb wfgw. Drgbibv awhgbwwb: gfuihwergb rg ywrgyf.";
text = text.replaceAll("[,^%$#@!^:;'/\"&*()?><\\-.]", "").replaceAll(" ", " ");
ArrayList<String> res = new ArrayList<>();
res.add(Arrays.toString(text.split(" ")));
System.out.println(res); // Задача из строки изъять все слова начинающиеся с "a" и поместить в массив
Iterator iterator = res.iterator();
while (iterator.hasNext()) {
String a = String.valueOf(iterator.next());
if ("a".equals(String.valueOf(a.charAt(0)))) {
System.out.println(a);
} else {
iterator.remove();
}
}
while (iterator.hasNext()) {
System.out.println("AAAAAAAAA chto za fygniya");
}
}
}
如果索引0 则输出:
[[aajiwi, aiwefhfhwe, wagw, gerhbdf, aiwrhgwbdb, wfgw, Drgbibv, awhgbwwb, gfuihwergb, rg, ywrgyf]]
Process finished with exit code 0
如果索引1 则输出:
[[aajiwi, aiwefhfhwe, wagw, gerhbdf, aiwrhgwbdb, wfgw, Drgbibv, awhgbwwb, gfuihwergb, rg, ywrgyf]]
[aajiwi, aiwefhfhwe, wagw, gerhbdf, aiwrhgwbdb, wfgw, Drgbibv, awhgbwwb, gfuihwergb, rg, ywrgyf]
Process finished with exit code 0
为什么if会返回 false?
您应该在逐步调试模式下运行您的程序,以确保它不完全符合预期,而是完全符合其编码的目的。
所提供代码中的主要问题在于:
因为它将单个字符串作为调用结果写入列表
res,即整个字符串数组的字符串表示形式:Arrays.toString(text.split(" "))"[aajiwi, aiwefhfhwe, wagw, gerhbdf, aiwrhgwbdb, wfgw, Drgbibv, awhgbwwb, gfuihwergb, rg, ywrgyf]"当然,这样的字符串的第一个字符是
'[',第二个字符是'a',并且将来列表迭代器res将只处理这个单个字符串。因此,首先应该正确地将字符串数组写入列表中
res,例如使用以下方法Collections::addAll(Collection<? super T> c, T ... elements):或使用以下方法
Arrays.asList:之后,您应该使用迭代器重写该部分:使其键入,在检查第一个字符时删除不必要的字符串转换,使用
String::startsWith如果您仍然需要获取问题陈述中所示的单词数组作为结果,那么您将必须转换结果列表
res:还应该注意的是,使用恐慌消息循环迭代器:
while (iterator.hasNext()) { System.out.println("УЖОС!");}本身没有意义,因为迭代器完成了上一个循环中的工作,但如果不是这样,那么这个循环将是无限的。
解决主要问题的可能替代方法:
Matcher::find:其中
\\ba\\p{L}*描述了以下单词格式:单词边界\\b,英语单词的第一个字母a后跟0个或多个其他字母\\p{L}*text.split("\\P{L}+"),分隔符是 1 个或多个任何非字母字符:要将字符串数组添加到列表中,您需要使用: