Почему в стеке используется индекс на основе 1, а не 0, как в массиве в Java? - PullRequest
3 голосов
/ 26 января 2020

Почему реализация Stack в Java возвращает позицию на основе 1 из верхней части стека для метода search(Object), где расположен объект, а не позицию на основе 0, как мы обычно делаем в массиве. Есть ли для этого особая причина или это решает какую-либо конкретную проблему c, если это не решается иначе, если мы используем индекс на основе 0?

Ответы [ 2 ]

1 голос
/ 26 января 2020

Вы можете увидеть в документах

... этот метод возвращает расстояние от вершины стека вхождения, ближайшего к вершине стека; считается, что самый верхний элемент в стеке находится на расстоянии 1 ...

Метод вычитает основанный на 0 lastIndexOf() из базового класса Vector из размера стека.

Из исходного кода

public synchronized int search(Object o) {
    int i = lastIndexOf(o);

    if (i >= 0) {
        return size() - i;
    }
    return -1;
}

Если в стеке был один элемент, скажем «A», он будет самым верхним элементом, поэтому расстояние от верха будет быть 1. size() - lastIndexOf("A") == 1

1 голос
/ 26 января 2020

Позиция , возвращаемая Stack.search, относится к концу структуры данных, тогда как индексы - к началу. Диапазоны обычно указываются как полуоткрытые интервалы, поэтому имеет смысл, что расстояние первого элемента от границы не равно нулю. Аналогичный метод List.lastIndexOf дает значение с начала списка. Сумма значений, возвращаемых search и lastIndexOf, равна size.

@ TJCrowder также указывает на то, что позиция search соответствует количеству pop с, которые вам нужно сделать, чтобы получить этот элемент.

Обратите внимание, что состояние документации API:

Более полный и согласованный набор операций стека LIFO обеспечивается интерфейсом Deque и его реализациями, которые следует использовать. в предпочтении этому классу.

Редактировать: Забавно, он продолжает предлагать этот код (не удосужившись связать тип Deque):

Deque<Integer> stack = new ArrayDeque<Integer>();

Из-за неправильных решений Deque является Queue. Таким образом, вы могли, но не должны писать:

Queue<Integer> doNotDoThisFFS = new ArrayDeque<Integer>();

Правильное заклинание для записи "Stack<Integer> stack();":

Queue<Integer> stack = Collections.asLifoQueue​(new ArrayDeque<Integer>());
...