Java 字符串外观相同但不匹配;列表迭代器异常

Java 字符串外观相同但不匹配;列表迭代器异常,java,Java,我是新来的,所以我不确定在同一篇文章中有两个问题是否合适,所以如果我不想告诉我(很好!),我会在这里改成一个问题,然后在其他地方开始另一篇文章 第一个问题: 下面第5-8行我指的是两个字符串,我需要比较它们是否相同。我正在使用getUserInput()方法从终端的用户那里获取响应,然后让它继续打印这两个字符串,这样我就可以直观地检查它们,并且它们是一样的。但是,当它们相同时本应运行的if部分从不运行,而else部分总是运行 第二个问题: 在下面的else部分中,每当currentcump的运行

我是新来的,所以我不确定在同一篇文章中有两个问题是否合适,所以如果我不想告诉我(很好!),我会在这里改成一个问题,然后在其他地方开始另一篇文章

第一个问题:

下面第5-8行我指的是两个字符串,我需要比较它们是否相同。我正在使用
getUserInput()
方法从终端的用户那里获取响应,然后让它继续打印这两个字符串,这样我就可以直观地检查它们,并且它们是一样的。但是,当它们相同时本应运行的
if
部分从不运行,而
else
部分总是运行

第二个问题:

在下面的
else
部分中,每当
currentcump
的运行状况降低到
<1
时,我就会遇到一个我以前从未见过的异常块,我不知道该怎么办

这是我的代码,然后在下面粘贴异常:

for (Chump currentChump : chumpArray) {
    System.out.println(" ");
    String playerChoice = helper.getUserInput(
                          "Type the name of the Weapon that you wish to use.");
    System.out.println(playerChoice);
    System.out.println(currentChump.getWeakness().toLowerCase());
    if (currentChump.getWeakness().toLowerCase() == playerChoice) {
        chumpArray.remove(currentChump);
    } // END IF
    else {
        while (PlayerIsAlive && currentChump.getHealth() > 0) {
            int damage = (int) Math.floor((Math.random() * 6) + 1);
            System.out.println(currentChump.getName() + " has "
                             + currentChump.getHealth() + "health remaining.");
            currentChump.setHealth(currentChump.getHealth() - damage);
            System.out.println("You hit the enemy for " 
                             + damage + " points of damage.");
            System.out.println(currentChump.getName() + " has " 
                             + currentChump.getHealth() + " health remaining.");
    System.out.println(" ");
            if (currentChump.getHealth() < 1) {
                chumpArray.remove(currentChump);
            } // END IF
            else {
                int damage2 = (int) Math.floor((Math.random() * 4) + 1);
                player.setHealth(player.getHealth() - damage2);
                if (player.getHealth() < 1) {
                    PlayerIsAlive = false;
                } // END IF
            } // END WHILE
        } // END ELSE
    } // END ELSE
} // END FOR
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at ArenaGameCopy.startPlaying(ArenaGameCopy.java:87)
at ArenaGameCopy.main(ArenaGameCopy.java:168)

当您要从列表中删除项并使用而不是修改基础列表时,请使用
迭代器
循环到

引用

…通常不允许一个线程修改集合 而另一个线程正在对其进行迭代。总的来说 在这些情况下,迭代是未定义的。某迭代器 实现(包括所有通用集合的实现) JRE提供的实现可以选择抛出 检测到此行为时发生异常。执行此操作的迭代器是 我们称之为fail fast迭代器,因为它们失败迅速且干净,而不是 在一个不确定的时间里,冒着任意的、不确定的行为的风险 未来的时间

请注意,此异常并不总是表示对象具有 被另一个线程同时修改。如果是单线程 发出一系列违反 对象时,该对象可能会引发此异常。例如,如果 线程在集合上迭代时直接修改集合 集合,迭代器将抛出 例外情况。

请注意,通常不能保证快速失效行为 说起来,在有人在场的情况下,不可能做出任何硬性保证 未同步的并发修改。快速失败操作抛出 ConcurrentModificationException尽最大努力。因此, 编写依赖此异常的程序是错误的 其正确性:ConcurrentModificationException仅应使用 检测错误


我来帮你。阅读代码中的注释:

import java.util.*;

/**
  Hello! Welcome to basics.
  This is what called a SSCCE.
  Next time anyone asks for it, do it.
  Because, 90% of the times, creating SSCCE will help you identify the issue.
  Hope you learn something from these lines.

  To compile and execute this code do the following:
  a. Paste this class from import to last closed bracket in a 
     file named Test.java
  b. javac Test.java
  c. java Test
  Bliss!
*/
public class Test{

  public static void main(String[] args){
    // 1. Do not worry about these lines
    //    I am just creating some sample data
    List<String> chumpArray = Arrays.asList("Oh my god! You must know to create SSCCE".split("\\s"));
    chumpArray = new ArrayList<String>(chumpArray);
    System.out.println("List to be iterated: " + chumpArray);

    // 2. This is what I meant when I said to use an Iterator
    //    Obviously, your iterator will look like Iterator<Chump>
    for(Iterator<String> chumpIt = chumpArray.iterator(); chumpIt.hasNext();) {

        // 3. Materialize the current item
        String currentChump = chumpIt.next();
        System.out.println("Currently on: " + currentChump);

        // 3. String comparison
        //    ==            WRONG
        //    .equals       RIGHT
        if (currentChump.toLowerCase().equals("you")) {
          System.out.println("DELETING: " + currentChump);
          // 4. Just ask the iterator to remove the current Item
          chumpIt.remove();
          // Was it really so hard?!
        }
    }
    System.out.println("List after delete: " + chumpArray);
  }
}
HTH

Nishant

您不能使用==来比较字符串,因为==将比较对象。。。不是字符串的值

if(currentChump.get弱点().toLowerCase()==playerChoice)

应该是

if (currentChump.getWeakness().toLowerCase().equals(playerChoice))


第二个问题似乎是您试图修改另一个线程中的对象(您的列表)。

第一个问题

Exception in thread "main" java.util.ConcurrentModificationException
在比较字符串时始终使用

==
操作符所做的是检查对象是否是一个相同的对象

这似乎对字符串起作用的唯一原因是一种叫做

这意味着,除非已显式使用字符串构造函数,否则具有相同字符序列的引用将指向相同的字符串对象。这是为了减少内存使用

第二个问题

Exception in thread "main" java.util.ConcurrentModificationException
这是由于使用增强的for循环修改正在迭代的结构造成的

这解释了引发异常的原因

在迭代器的每个next()方法调用中

  final void checkForComodification() {
      if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
  }
方法,以检查列表中是否存在机会。 如果没有,则抛出ConcurrentModificationException 匹配

其他评论


出于您似乎部分遵守的约定,您可以将布尔变量从
PlayerIsAlive
重命名为
isplayerisalive
。在camelCase中,第一个小数值和一个“是”立即向读者表明这是一个真/假值。

我很高兴有人认为我很棒。:)一般来说,您应该这样做。谢谢Jeffrey,我以后会这样做。我尝试使用迭代器,但我得到了相同的异常。编辑了OP,添加了新代码。没有放例外,因为它是完全相同的。所以我试图编辑OP,但它说它找不到页面。。。这是因为Lee Taylor编辑了我的标题吗?有人愿意教我如何使用迭代器来修改代码吗?我以前从来没有用过它,我已经看了一段时间了,我真的不明白它。我肯定会有一个新的工具在我的工具包后记!谢谢大家的帮助!请提供一个,我会帮你做周日外卖:)谢谢,尼桑。现在我要开始弄清楚那是什么!哇,你这么做真是太好了!昨天上班的时候我试着花点时间在SSCCE上,但我真的太忙了,直到现在才能够重新开始编码。非常感谢你的帮助,将来我会提供SSCCE,希望在这个过程中我能自己解决问题。不,不,事实证明,按照你的指示更好地解决了问题。我开始做一个SSCCE,我能够解决我自己的问题。你就是尼桑。我是一个非常严肃的人,如果有什么我能为你做的,请告诉我。第二期错了。这根本不是多线程。它是在遍历列表时从列表中删除一个项。
(Chump currentChump:chumpArray)
语句在引擎盖下创建一个
迭代器。
  final void checkForComodification() {
      if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
  }