Материал: 6 - Презентация 2 - Дженерики, Абстрактные типы данных, Стек

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Центр дистанционного обучения

Абстрактные типы данных (ADT)

Для чего нужно присваивание “elements[top] = null” в pop?

MyStack<String> stack = new ArrayStack<>(new String[10]); stack.push(“A”.repeat(1_000_000));

stack.pop();

//Без обнуления ссылка на строку из миллиона символов

//так и будет находиться в массиве до следующего push,

//и сборщик мусора не будет освобождать эту память,

//хотя она по сути уже не нужна

online.mirea.ru

Центр дистанционного обучения

Абстрактные типы данных (ADT)

Из-за ограничения на generics мы не можем вызвать new E[] в конструкторе ArrayStack, и вынуждены передавать массив извне. Это можно обойти с помощью некоторых хаков.

online.mirea.ru

Центр дистанционного обучения

Абстрактные типы данных (ADT)

public class ArrayStack2<E> implements MyStack<E> {

private final Object[] elements;

private int top = -1;

public ArrayStack2(int size) { this.elements = new Object[size];

}

@Override public E pop() {

if (isEmpty()) throw new IllegalStateException("Stack is empty: cannot pop"); E result = (E) elements[top];

elements[top] = null; top--;

return result;

}

}

online.mirea.ru

Центр дистанционного обучения

Абстрактные типы данных (ADT)

В общем случае эта строка:

E result = (E) elements[top]; // Object[] elements

может вызывать ClassCastException, поэтому компилятор выдает для нее предупреждение:

ArrayStack2.java uses unchecked or unsafe operations

Но в нашем случае мы можем гарантировать, что массив elements всегда содержит только элементы типа E, хотя он и объявлен как массив Object, так как мы помещаем в массив элементы только в методе push со значением типа E.

online.mirea.ru

Центр дистанционного обучения

Абстрактные типы данных (ADT)

Компилятор Java недостаточно умен, чтобы это понять. Если бы мы вызывали код “elements[0] = 42”, тогда компилятор был бы прав – наш код не работал бы с E, отличным от Integer.

Компилятор можно попросить не выдавать предупреждение:

@SuppressWarnings("unchecked") @Override

public E pop() {

if (isEmpty()) throw new IllegalStateException("Stack is empty: cannot pop"); E result = (E) elements[top];

elements[top] = null; top--;

return result;

}

При этом отсутствие ClassCastException гарантирует не

компилятор, а программист.

online.mirea.ru

Источник: https://studfile.net/preview/16403810/