如何创建处理Java中的数组泛型的sureCapacity方法

时间:2019-03-03 22:43:48

标签: java arrays list object generics

因此,我正在创建一个名为“ Sack”的通用数据结构。在此方法中,我将物品添加到麻袋,抓取随机物品,查看物品是否为空或丢弃其内容等。此外,我还将其创建为扩展以容纳所需的物品。

我目前正在研究sureCapacity方法,该方法应确保麻袋具有其参数值的容量,如果没有,请为麻袋创建一个新的基础数据结构,该结构要大于麻袋当前容量的两倍。麻袋。

我尝试了许多方法来执行此操作,但是我一直收到错误消息。我将删除我的大部分代码,还删除我尝试过的两种方法,并指出我收到的错误。

public class Sack<E>
{
 public static final int DEFAULT_CAPACITY = 10;
 private E [] elementData;
 private int size;

@SuppressWarnings("unchecked")
   public Sack()
   {
     elementData = (E[]) new Object[DEFAULT_CAPACITY];
   }
@SuppressWarnings("unchecked")
public Sack(int capacity)
{
    if(capacity < 0)
    {
        throw new IllegalArgumentException("capacity " + capacity);
    }
    this.elementData = (E[]) new Object[capacity];
}

public boolean isEmpty()
{
    if(size == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
 public E [] dump()
 {
   E [] E2 = Arrays.copyOf(elementData, size);
   for(int i = 0; i < size; i++)
   {
      elementData[i] = null;

   }
   size = 0;
    return E2;
}

第一个: 在此错误中,主要是我在运行测试时说

AssertionFailedError:确保Capacity无法正常工作

private void ensureCapacity(int capacity)
{
   if (size != capacity)
    {
        int newCapacity = (capacity * 2) + 1;
        elementData[capacity] = elementData[newCapacity];
    }
}

稍作更新,我将发布测试。你们可以检查出来并告诉我,但是我根本无法修改测试。只有我的代码。我注释了第一行,因为这是我的错误发生的地方。

@Test
public void testEnsureCapacity()
{
    assertEquals(2, ensureCapacity.getModifiers(), "ensureCapacity does not have the correct modifiers"); // My error occurs here currently. 
    try
    {
        for(int i=0; i<=10; ++i)
        {
            ensureCapacity.invoke(s, i);
            assertEquals(10, ((Object[])elementData.get(s)).length, "ensureCapacity is not working correctly (capacity changing unnecessarily)");
        }
        ensureCapacity.invoke(s, 11);
        assertEquals(21, ((Object[])elementData.get(s)).length, "ensureCapacity is not working correctly (capacity not increased correctly)");

        Random rand = new Random();
        int capacity = rand.nextInt(100)+1;
        s = new Sack<Integer>(capacity);
        for(int i=0; i<=capacity; ++i) {
            ensureCapacity.invoke(s, i);
            assertEquals(capacity, ((Object[])elementData.get(s)).length, "ensureCapacity is not working correctly (capacity changing unnecessarily)");
        }
        ensureCapacity.invoke(s, capacity+1);
        assertEquals(capacity*2+1, ((Object[])elementData.get(s)).length, "ensureCapacity is not working correctly (capacity not increased correctly)");
    } catch (Exception e) {
        fail("ensureCapacity is not working correctly");
    }
}

2 个答案:

答案 0 :(得分:0)

您因为“删除”而收到该错误-即。泛型类型仅用于编译时,但会从已编译的字节码中“擦除”。这意味着运行时不知道“ E”代表哪种类型,因此无法创建任何泛型类型的实例(或数组)。 (另请参见What is erasure)。

因此,您可以像已经完成的操作一样,替换该错误行以创建对象数组:

E [] newList = (E[]) new Object[DEFAULT_CAPACITY];

但这不是理想的-更好的方法是直接创建正确类型的数组。解决该问题的方法是修改构造函数,使其采用实际运行时类型Class的参数(我喜欢将此参数称为“ clazz”),因此可以方便地使用该引用-

private Class<E> clazz;

@SuppressWarnings("unchecked")
public Sack(Class<E> clazz, int capacity)
{
    if(capacity < 0)
    {
        throw new IllegalArgumentException("capacity " + capacity);
    }
    this.clazz = clazz;
    this.elementData = (E[]) Array.newInstance(this.clazz, capacity);
}

,当然还要用:替换该错误行:

E [] newList = (E[]) Array.newInstance(this.clazz, capacity);

编辑“第一”和“单元测试”:

因此,在您的单元测试中,我假设“ ensureCapacity”是Method类型的变量。 该断言指出期望有两个修饰符,但实际值只有一个。 我希望您会在课堂上介绍修饰符,但简要地说,您可以考虑修饰符有两个“组”-“访问修饰符”和其余修饰符(即“非访问修饰符”)-参见{{3} }。

正如我提到的,您的sureCapacity方法上已经有一个修饰符-即Access-Modifier“ public”。因此,您得到的断言错误意味着应该在它旁边有另一个(不可访问的)修饰符。我只能猜测第二个修饰符是哪个(同样,该修饰语将在您的课程中介绍),但这将是上面dzone文章中的其中一个-请阅读该文章,并将其与您所教的内容进行比较

像这样的东西:

private void ensureCapacity(int capacity)
{
   if (size > capacity)
   {
       int newCapacity = (capacity * 2) + 1;
       elementData = Arrays.copyOf(elementData, newCapacity);
   }
}

答案 1 :(得分:0)

我知道了,这是我的问题的解决方案。

private void ensureCapacity(int capacity)
{
    if (elementData.length < capacity)
    {
        int newCapacity = elementData.length * 2 + 1;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}