Самый эффективный способ перевернуть стек и добавить его в ArrayList - PullRequest
0 голосов
/ 07 августа 2009

У меня есть две коллекции - ArrayList и Stack. Я использую стек, потому что мне нужна была простая функциональность pop / push для этого фрагмента кода. ArrayList - это, по сути, переменная out, так как это небольшой фрагмент кода в функции.

Итак, переменные определены как таковые, затем выполняется код для добавления элементов в стек.

ArrayList<String> out = new ArrayList<String>();

/* other code.. */

Stack<String> lineStack = new Stack<String>();

/* code that adds stuff to the stack */

Вопрос в том, что теперь, когда у меня есть полностью заполненный стек, как мне поместить его в выходной ArrayList в обратном порядке, а затем в порядке всплывающих окон.

Моё первое придуманное решение было

 while(!lineStack.empty()) {
     out.add(0, lineStack.pop());
 }

... что работает, но я беспокоюсь об эффективности добавления элемента в начало ArrayList (который заставляет все существующие элементы перемещаться ... это связанный список (я полагаю) ... большое дело. но все еще вызывает беспокойство). Кроме того, я запускаю это через цикл ... возможно, излишне.

Итак, мое второе решение, которое не включало в себя циклы (по крайней мере, в моем коде, я уверен, что это делают внутренние вызовы).

 List l = lineStack.subList(0, lineStack.size());
 out.addAll(l);

Я знаю, что мне не нужно распределять список, но он сохранится для более чистого кода. Однако я не уверен, что это даст мне особенно полезное увеличение производительности.

Итак, мой вопрос: какой из них, вероятно, будет наиболее эффективным для наборов размеров от МАЛЕНЬКОГО до СРЕДНЕГО? Если бы было более эффективное решение, что бы это было?

Ответы [ 5 ]

23 голосов
/ 07 августа 2009

Порядок реализации Iterable<T>, равный Stack<T>, идет в любом порядке, который вы хотите, поэтому вы можете просто использовать

new ArrayList<String>(stack);

Вот короткий, но полный пример:

import java.util.*;

public class Test
{
    public static void main(String[] args)
    {
        Stack<String> stack = new Stack<String>();
        stack.push("Bottom");
        stack.push("Middle");
        stack.push("Top");

        List<String> list = new ArrayList<String>(stack);

        for (String x : list)
        {
            System.out.println(x);
        }
    }
}

Это распечатывает:

Bottom
Middle
Top

(это порядок, противоположный тому, который вы получили бы, если бы вы получили их).

РЕДАКТИРОВАТЬ: Еще один вопрос - вам действительно нужно это в ArrayList<String> в любом случае? Stack<T> реализует List<T>; какие особенности ArrayList вам нужны? (Я не говорю, что вы не нуждаются в них, просто проверяете!)

3 голосов
/ 03 марта 2016

Стек является подклассом коллекций и коллекций имеет обратный метод , так что вы можете просто сделать -

   Stack originalStack = ...
   Collections.reverse(originalStack);
2 голосов
/ 23 апреля 2014

Если вам не нужен массив, но сработал бы другой стек, почему бы и нет:

Stack<String> reversedStack = new Stack<String>(); while (!oldStack.empty()) { reversedStack.push(oldStack.pop()); }

Быстро, просто и легко увидеть, что он делает.

1 голос
/ 07 августа 2009

Создайте подкласс ArrayList и добавьте метод pop и push. Используйте это как класс Stack.

Когда вы будете готовы, присвойте ее переменной Arraylist, и вы готовы

0 голосов
/ 07 августа 2009

использовать Stack.toArray просто:

@Test
public void stackToList() {
    Stack<String> stack = new Stack<String>();
    stack.push("aaa");
    stack.push("bbb");
    stack.push("ccc");
    List<String> list=  Arrays.asList(stack.toArray(new String[0]));
    Assert.assertEquals(Arrays.asList("aaa", "bbb", "ccc"), list);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...