我怎么避免ArrayIndexOutOf边界异常或IndexOutOf边界异常?

本教程将介绍我如何避免ArrayIndexOutOf边界异常或IndexOutOf边界异常?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

问题描述

如果您的问题是

这是最全面的canonical信息收集
java.lang.ArrayIndexOutOfBoundsException主题以及java.lang.IndexOutOfBoundsException

类似的问题有很多,而且所有问题都有模糊的无代码答案,或者大多数问题都非常具体和局限于手头的问题,没有解决在所有情况下都完全相同的根本原因。


推荐答案

什么是java.lang.ArrayIndexOutOf边界异常/java.lang.IndexOutOf边界异常?

JavaDoc简略说明:

抛出以指示已使用非法的
索引。索引为负值或大于或等于
数组的大小。

发生这种情况的原因是什么?

此异常表示您试图访问
数组或数组支持的列表,并且该索引不存在。

Java使用基于0的索引。这意味着所有索引都以0AS开头
第一个元素的索引(如果它包含任何元素)。

IndexOutOfBoundsException消息非常明确,通常采用以下形式:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

其中Index是您请求的不存在的索引,Size是要索引到的结构的长度。

如您所见,Size: 1表示唯一有效的索引是0,您要求的是索引1处的内容。

例如,如果您有对象或基元类型的原始Array
有效索引是0.length - 1,在以下示例中,有效索引是0, 1, 2, 3,

final String days[] { "Sunday", "Monday", "Tuesday" }
System.out.println(days.length); // 3
System.out.println(days[0]); // Sunday
System.out.println(days[1]); // Monday
System.out.println(days[2]); // Tuesday
System.out.println(days[3]); // java.lang.ArrayIndexOutOfBoundsException

这也适用于ArrayList以及可能由Array支持并允许直接访问索引的任何其他Collection类。

怎么避免java.lang.ArrayIndexOutOfBoundsException/java.lang.IndexOutOfBoundsException

直接按索引访问时:

此操作使用Guava将原始原语int[]数组转换为
ImmutableList<Integer>。然后它使用Iterables类来安全地
获取特定索引处的值,并在以下情况下提供默认值
该索引不存在。在这里,我选择-1表示无效
索引值。

final List<Integer> toTen = ImmutableList.copyOf(Ints.asList(ints));
System.out.println(Iterables.get(toTen, 0, -1));
System.out.println(Iterables.get(toTen, 100, -1));

如果您由于某种原因不能使用Guava,则可以轻松地滚动您自己的函数来执行相同的操作。

private static <T> T get(@Nonnull final Iterable<T> iterable, final int index, @Nonnull final T missing)
{
 if (index < 0) { return missing; }
 if (iterable instanceof List)
 {
  final List<T> l = List.class.cast(iterable);
  return l.size() <= index ? l.get(index) : missing;
 }
 else
 {
  final Iterator<T> iterator = iterable.iterator();
  for (int i = 0; iterator.hasNext(); i++)
  {
final T o = iterator.next();
if (i == index) { return o; }
  }
  return missing;
 }
}

迭代时:

如果需要,以下是迭代原始Array的惯用方法
要了解索引和值,请执行以下操作:

这容易受到主要原因的的影响
java.lang.ArrayIndexOutOfBoundsException的:

使用传统的-循环:

final int ints[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < ints.length; i++)
{
 System.out.format("index %d = %d", i, ints[i]);
}

使用增强的循环:

以下是使用以下命令迭代原始Array的惯用方法

for (final int i : ints)
{
 System.out.format("%d", i);
 System.out.println();
}

使用类型安全迭代器&lt;T&gt;:

下面是使用增强的迭代原始Array的安全方法
for循环并跟踪当前索引,避免
遇到java.lang.ArrayIndexOutOfBoundsException

这使用芭乐轻松地将int[]转换为Iterable
每个项目都应包括它。

final Iterator<Integer> it = Ints.asList(ints).iterator();
for (int i = 0; it.hasNext(); i++)
{
 System.out.format("index %d = %d", i, it.next());
}

如果您不能使用芭乐或者您的int[]很大,您可以自己滚动ImmutableIntArrayIterator,如下所示:

public class ImmutableIntArrayIterator implements Iterator<Integer>
{
 private final int[] ba;
 private int currentIndex;

 public ImmutableIntArrayIterator(@Nonnull final int[] ba)
 {
  this.ba = ba;
  if (this.ba.length > 0) { this.currentIndex = 0; }
  else { currentIndex = -1; }
 }

 @Override
 public boolean hasNext() { return this.currentIndex >= 0 && this.currentIndex + 1 < this.ba.length; }

 @Override
 public Integer next()
 {
  this.currentIndex++;
  return this.ba[this.currentIndex];
 }

 @Override
 public void remove() { throw new UnsupportedOperationException(); }
}

并使用与芭乐相同的代码。

如果您绝对必须具有项目的序号,则以下是最安全的方法。

// Assume 'los' is a list of Strings
final Iterator<String> it = los.iterator();
for (int i = 0; it.hasNext(); i++)
{
 System.out.format("index %d = %s", i, it.next());
}

此技术适用于所有。它不是分析,但它确实为您提供迭代中的当前位置,即使对于没有本机的内容也是如此。

最安全的方式:

最好的方法是始终使用来自番石榴的ImmutableLists/Set/Maps作为
嗯:

final List<Integer> ili = ImmutableList.copyOf(Ints.asList(ints));
final Iterator<Integer> iit = ili.iterator();
for (int i = 0; iit.hasNext(); i++)
{
 System.out.format("index %d = %d", i, iit.next());
}

摘要:

    使用原始数组很难使用,在大多数情况下应该避免使用。它们很容易受到有时微妙的的影响,这甚至可以追溯到BASIC

    的日子

    现代Java习惯用法使用正确的类型安全,并尽可能避免使用原始结构。

    现在几乎所有情况下都首选不可变类型。

    Guava是现代Java开发不可或缺的工具包。

好了关于我怎么避免ArrayIndexOutOf边界异常或IndexOutOf边界异常?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。

0
没有账号?注册  忘记密码?