插入方法作为数组的一部分

时间:2015-02-18 17:17:54

标签: java arrays generics

这种方法一直困扰着我好几个小时。它应该采用任何数据类型的类型X array的一部分。这是我第一次使用泛型array和调试器。

我从测试中得到的错误是:

expected: 'hello' but was 'null' and 
0: ...ArrayOutOfBoundsException: 0

看起来ArrayOutOfBoundsException处理也没有被正确抛出。

我不知道该怎么做。我的删除功能似乎工作正常。

public void insert( int index, X item )
{
    if ( index > 0 || index < length )
    {
        length++;
        X[] obj2 = (X[]) new Object[obj.length - 1];
        for ( int i = 0; i == index; i++ )
        {
            obj2[i] = obj[i];
        }
        obj2[index] = item;
        for ( int i = index; i == length; i++ )
        {
            obj2[i + 1] = obj[i];
        }
        obj = obj2;
    }

    else
    {
        throw new java.lang.ArrayIndexOutOfBoundsException("" + index);
    }
}

@Test
public void testInsert()
{
    XArray<String> b = new XArray<String>();
    b.add("hello");
    b.add("bye");
    b.insert(1, "adios");
    assertEquals("hello", b.get(0));
    assertEquals("adios", b.get(1));
    assertEquals("bye", b.get(2));
    assertEquals(3, b.size());

    b.insert(1, "buenos dias");
    assertEquals(4, b.size());
    assertEquals("hello", b.get(0));
    assertEquals("buenos dias", b.get(1));
    assertEquals("adios", b.get(2));

    b.insert(0, "hi");
    assertEquals(5, b.size());
    assertEquals("hi", b.get(0));
    assertEquals("hello", b.get(1));

    b.insert(4, "see ya");
    assertEquals(6, b.size());
    assertEquals("see ya", b.get(4));
    assertEquals("bye", b.get(5));
}

2 个答案:

答案 0 :(得分:3)

你有一些问题。

1)假设length是一个实例变量,它反映了length数组的obj,那么你实际上想要进行以下测试:

if (index >= 0 && index <= length)

这将测试您的 new 项索引是否为0或更多,或者比当前obj数组中的最大索引大1(即等于当前数组长度)。 这在很大程度上取决于您的预期合同我认为您可以&#34;插入&#34;在列表的末尾,但您可能必须将其限制为仅插入中间,因此仅当存在另一个元素时。在这种情况下,你想要

if (length > 0 && index >= 0 && index < length)

注意:您需要测试&&,而不是||,因为您需要满足所有条件。如果你想在开头做一个更标准的参数有效性检查,你可以这样做:

    if (index < 0 || index > length)
      throw new java.lang.ArrayIndexOutOfBoundsException("" + index);

这样做的好处是无需else块,并且可以略微减少代码嵌套。

2)然后你增加this.length,然后你做new Object[obj.length - 1];,这没有任何意义。我怀疑你想做:

  length++;
  @SuppressWarnings("unchecked")
  X[] obj2 = (X[]) new Object[this.length];

或更好:

  @SuppressWarnings("unchecked")
  X[] obj2 = (X[]) new Object[++length];

3)你的第一个循环for ( int i = 0; i == index; i++ ),它应该是:

for (int i = 0; i < index; i++)

这是因为循环条件语句不会测试突破条件(即当这是真的时停止)但是对于延续条件(即在i小于index时继续) )

4)你的第二个循环是for ( int i = index; i == length; i++ ),应该这样做:

for (int i = index; i < length - 1; i++)

这是因为你的长度有所增加,但你使用i来引用原始数组索引,而不是更大的数组索引。

总而言之,我认为它看起来像下面的代码。

这里最大的问题可能就是你的测试方法。你在一个大型测试中有几个测试。这并不能帮助你隔离个别错误,并在不破坏调试器的情况下解决你的方法有什么问题(双关语无意,但我只是看到了它,所以我将离开它)。理想情况下,如果您的单元测试很小,集中和隔离,则不应该使用调试器。最后包括这些测试的例子。

class XArray<X> {
  private int length;
  private X[] obj;
  public XArray() {
    this.obj = initBackingArray(0);
    this.length = 0;
  }
  private X[] initBackingArray(int length) {
    @SuppressWarnings("unchecked")
    X[] result = (X[])new Object[length];
    return result;
  }
  public X get(int index) {
    return this.obj[index];
  }
  public int size() {
    return this.length;
  }
  public void add(X item) {
    insert(length, item);
  }
  public void insert( int index, X item )
  {
    if (index >= 0 && index <= length)
    {
      @SuppressWarnings("unchecked")
      X[] obj2 = (X[]) new Object[++length];
      for (int i = 0; i < index; i++)
      {
        obj2[i] = obj[i];
      }
      obj2[index] = item;
      for (int i = index; i < length - 1; i++)
      {
        obj2[i+1] = obj[i];
      }
      obj = obj2;
    }

    else
    {
      throw new java.lang.ArrayIndexOutOfBoundsException("" + index);
    }
  }
}

示例测试:

@Test
public void testAddOnceWorks()   {
    XArray<String> b = new XArray<String>();
    b.add("hello");
}
@Test
public void testAddTwiceWorks()   {
    XArray<String> b = new XArray<String>();
    b.add("hello");
    b.add("bye");
}
@Test
public void testInsertOnEmptyWorks()   {
    XArray<String> b = new XArray<String>();
    b.insert(0, "hello");
}
@Test
public void testAddOnceInsertBeforeWorks()   {
    XArray<String> b = new XArray<String>();
    b.add("hello");
    b.insert(0, "hello");
}

答案 1 :(得分:1)

首先,您的边界检查逻辑不正确。 index可能的每个值都大于0 小于length。这会导致您尝试创建的ArrayIndexOutOfBoundsException不被抛出。 (如果你的数组超出界限,它可能会抛出自己的AIOOBE。)

您应该确保满足这两个条件。使用&&代替||

if ( index > 0 && index < length )

此外,在将旧元素复制到新数组时,您需要意识到for循环条件为true意味着&#34;继续前进&#34;而不是&#34;停止& #34 ;.在index尚未达到length时继续循环播放。将==更改为<

for ( int i = 0; i < index; i++ )

(另一个for循环需要进行类似的更改。)