在我的Android应用程序中获取IndexOutOfBounds异常



此代码跟踪玩家购买的导弹,并将最新的3枚导弹设置在导弹选项列表的顶部,以便玩家轻松再次购买。玩家购买导弹后,游戏会崩溃,但前提是他们购买了某些导弹或购买了一定数量的导弹。

Process: com.apps.fast.counterforcetest, PID: 16063
java.lang.IndexOutOfBoundsException: Index: 5, Size: 3
at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
at java.util.LinkedList.remove(LinkedList.java:525)
at com.apps.fast.launch.components.ClientDefs.SetMissilePreferred(ClientDefs.java:199)
at com.apps.fast.launch.launchviews.PurchaseLaunchableView$1$1.onClick(PurchaseLaunchableView.java:198)

以下是CLientDefs.java:199中错误指向的代码

public static void SetMissilePreferred(int lMissile) {
// Set a purchased missile to go to the top of the preferred list.
if (MissilePreferences == null)
MissilePreferences = new LinkedList<>();
if (MissilePreferences.contains(lMissile))
MissilePreferences.remove(lMissile); //<---- Line 199
MissilePreferences.push(lMissile);
if (MissilePreferences.size() > PREFERENCE_LIST_SIZE)
MissilePreferences.removeLast();
}

MissilePreferences是一个整数列表。

这里有点混乱:

if (MissilePreferences.contains(lMissile))
MissilePreferences.remove(lMissile);

lMissileint,对吧?代表身份证?因此,当您调用contains时,您正在检查该ID是否存在于MissilePreferences中。您想知道List是否包含该int

这是contains:的方法签名

public boolean contains(Object o)

它不像int那样需要基元,它需要Object——所以int被自动装箱到Integer中——这是有道理的,因为List也不能包含基元,只能包含对象。MissilePreferencesIntegers的列表。


所以没关系,它将您的int转换为Integer,并告诉您它是否存在于Integers的列表中,完美!但是你用原来的int调用remove。这种方法有两个版本需要一个参数:

public boolean remove(Object o)

从该列表中删除指定元素的第一个出现(如果存在(。

public E remove(int index)

删除此列表中指定位置的元素。

它们做了两件截然不同的事情。Object版本从列表中删除该对象的第一个实例。int版本将int视为索引,并删除该位置中的任何内容。

当您使用contains时,您将int视为要查找的列表中的一个元素,它会自动转换为Integer。你想对remove做同样的事情,但有一个不同版本的方法,它采用了你直接提供的int。显然,它不会自动装箱并调用其他方法!你必须自己做:

Integer missileId = new Integer(lMissile);
// explicitly passing an Integer object to both - only crucial for #remove
if (MissilePreferences.contains(missileId))
MissilePreferences.remove(missileId);

这就是你必须注意的——除了数组和你可能在其他地方遇到的一些特殊类之外,集合对象不包含基元,所以你经常想显式地使用它们包含的Object包装版本。在这种情况下,对int特别重要!

也就是说,你可以这样做:

MissilePreferences.remove(new Integer(lMissile));

不需要使用contains——只需调用remove,它就会删除第一个匹配对象(如果它有(。如果它删除了任何内容,它将返回true,以防您需要检查

尝试调试代码,以便了解列表中的元素以及要删除的元素。当你只是根据列表中的元素的值访问它时,我仍然困惑于如何获得索引越界异常。

相关内容

  • 没有找到相关文章

最新更新