字符串在视觉上相同但不匹配;列表迭代器异常



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

第一个问题:

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

第二个问题:

在下面的else部分中,每当currentChump的运行状况降低到< 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)

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

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

应该是

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

 if (currentChump.getWeakness().equalsIgnoreCase(playerChoice))

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

当您想从列表中删除项目时,使用Iterator循环到,并使用Iterator.remove()而不是修改底层列表。

引用JavaDoc

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

请注意,此异常并不总是表示对象具有被另一个线程同时修改。如果单个线程发出违反约定的方法调用序列对象,则该对象可能引发此异常。例如,如果线程在迭代集合,迭代器将抛出例外

请注意,通常情况下,不能保证快速故障行为说起来,在不同步的并发修改。失败快速操作投掷基于尽力而为的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);
  }
}

在执行此操作时,我们得到

tmp$ java Test
List to be iterated: [Oh, my, god!, You, must, know, to, create, SSCCE]
Currently on: Oh
Currently on: my
Currently on: god!
Currently on: You
DELETING: You
Currently on: must
Currently on: know
Currently on: to
Currently on: create
Currently on: SSCCE
List after delete: [Oh, my, god!, must, know, to, create, SSCCE]

HTH
Nishant

第一个问题

在比较字符串时始终使用equals!

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

这似乎适用于Strings的唯一原因是因为一种叫做实习的东西。

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

第二个问题

Exception in thread "main" java.util.ConcurrentModificationException

这是由于使用增强的for循环修改正在迭代的结构而导致的。

此链接解释了引发异常的原因。

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

  final void checkForComodification() {
      if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
  }

方法,以检查列表中是否有机会。这会引发ConcurrentModificationException,以防它们没有火柴

其他评论

出于您似乎部分尊重的约定,您可以将布尔变量从PlayerIsAlive重命名为isPlayerAlive。这是在camelCase中,带有第一个极小值和一个"is",以立即向读者表明这是一个真/假值。

最新更新