【问题标题】:Iterate through an Arraylist of Chars遍历字符的 Arraylist
【发布时间】:2024-01-22 05:34:01
【问题描述】:

我正在尝试创建一个输入字符串并返回拼写错误的方法(通过删除一些随机字符)。出于某种原因,我的迭代器在 id.remove() 的行上给了我一个空错误。有什么想法吗?

public static String getMissSpelledWord(String str) {
        Random random = new Random();
        char[] character = str.toCharArray();
        String misspelled = new String();


        ArrayList<Character> chars = new ArrayList<Character>();
        for (int i = 0; i < character.length; i++) {
            chars.add(character[i]);
        }

        for (Iterator < Character > id = chars.iterator(); id.hasNext();) {
            int remove = random.nextInt(3);
            if(remove == 0) {
                id.remove();
            }
        }

        for(char c : chars) {
            misspelled += c;
        }

        return misspelled;
    }

【问题讨论】:

  • 您需要在for 循环内调用id.next()。否则,第一次调用 remove 将不会指向任何内容。
  • 顺便说一句,您的整整一代 chars 可以简单地替换为 new ArrayList(Arrays.asList(str))

标签: java iterator char


【解决方案1】:

您不能在没有调用Iterator.next() 的情况下调用Iterator.remove()(正如链接的Javadoc 所指出的那样从基础集合中删除此迭代器返回的最后一个元素)。只需在循环体中添加一个id.next(),就像

for (Iterator<Character> id = chars.iterator(); id.hasNext();) {
    char ch = id.next(); // <-- add this.
    int remove = random.nextInt(3);
    if (remove == 0) {
        id.remove();
    }
}

【讨论】:

  • 谢谢!我就是这么想的,我只是不确定,因为我不需要用它来检查任何东西
  • @AZGames 我应该注意,如果没有它(假设它确实有效),循环将不会结束,因为 id.hasNext() 将继续返回 true (因为你从不消耗迭代器中的任何东西)。
【解决方案2】:

如果没有 ArrayList,只需在 char 数组中向前移动一个随机量,这样做会更简单。

public static String getMisspelledWord(String str) {
    Random random = new Random();
    char[] character = str.toCharArray();
    String misspelled = "";
    for (int i = 0; i < character.length; i += random.nextInt(3) / 2 + 1) {
        misspelled += character[i];
    }
    return misspelled;
}

【讨论】:

  • i += random.nextInt(3) / 2 + 1 yikes.
  • @Alexander 它应该有 1/3 的机会跳过给定的角色,这与删除 AZ Games 原始问题中的角色的机会相同
  • 我明白了,这只是你真正需要看看和思考的东西。这可以通过保持循环计数器递增 1 (i++) 和具有 boolean shouldSkipNextCharacter = Math.random() &lt; someProbability; if (shouldSkip) { i++; } 的主体来实现更易读
【解决方案3】:

Iterator.remove 抛出 IllegalStateException - 如果下一个方法有 还没有被调用,或者 remove 方法已经被调用了 在最后一次调用 next 方法之后。和 UnsupportedOperationException - 如果删除操作不是 受此迭代器支持。

在你的情况下,你不应该得到一个空错误,应该抛出一个IllegalStateException

考虑到您的用例,如果您在 id.remove(); 之前添加 id.next(); 直到迭代器具有元素,循环将运行并且它将一直运行直到字符为空,从而使您的拼写错误始终为空。

【讨论】:

    【解决方案4】:

    试试这个

        public static String getMissSpelledWord(String string) {
        char charArray[] = string.toCharArray();
        Random random = new Random();
        StringBuilder stringBuilder = new StringBuilder();
        for (int index = 0; index < charArray.length; index++) {
            if (random.nextInt(3) == 0) {
                continue;
            }
            stringBuilder.append(charArray[index]);
        }
        return stringBuilder.toString();
    }
    

    经过测试,工作正常

    【讨论】:

      最近更新 更多