Как создать метод sureCapacity, который работает с универсальными массивами в Java - PullRequest
0 голосов
/ 04 марта 2019

Итак, я создаю общую структуру данных с именем "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: sureCapacity работает неправильно

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 голосов
/ 06 марта 2019

Я понял, вот каково решение моего вопроса.

private void ensureCapacity(int capacity)
{
    if (elementData.length < capacity)
    {
        int newCapacity = elementData.length * 2 + 1;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}
0 голосов
/ 04 марта 2019

Вы получаете эту ошибку из-за "Erasure" - т.е.универсальные типы предназначены только для времени компиляции, но они «стираются» из скомпилированного байт-кода.Это означает, что среда выполнения не знает, какой тип представляет «E», поэтому не может создавать экземпляры (или массивы) какого-либо универсального типа.(См. Также Что такое стирание ).

Итак, вы можете заменить эту строку ошибки, чтобы создать массив объектов, как вы уже сделали:

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);

РЕДАКТИРОВАТЬ «ПЕРВЫЙ» И ИСПЫТАНИЕ НА БЛОК:

Итак, в вашем модульном тесте - я предполагаю »sureCapacity "- это переменная типа Method. Это утверждение утверждает, что он ожидает двух модификаторов, но фактическое значение он находит в одном.Я ожидаю, что вы рассмотрели модификаторы в своем классе, но вкратце вы можете считать, что есть две «группы» модификаторов - «Access-Modifiers» и остальные (то есть «Non-Access-Modifiers») - см. https://dzone.com/articles/all-about-java-modifier.

Как я уже упоминал, у вас уже есть один модификатор в вашем методе sureCapacity, а именно Access-Modifier "public".Таким образом, ошибка подтверждения, которую вы получаете, означает, что у вас должен быть другой (не доступный) модификатор рядом с ним.Я могу только догадываться, каким будет этот второй модификатор (опять же, который был бы рассмотрен в вашем классе), но он будет одним из тех, что описаны в статье о dzone выше - так что прочитайте эту статью и сравните ее с тем, чему вас учили.

Так что-то вроде:

private void ensureCapacity(int capacity)
{
   if (size > capacity)
   {
       int newCapacity = (capacity * 2) + 1;
       elementData = Arrays.copyOf(elementData, newCapacity);
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...