Java 如何从链表中生成堆栈?

Java 如何从链表中生成堆栈?,java,Java,我正试图创建一个堆栈来获取一个字符串并将每个字符串字符添加到其中,但有人告诉我,使用LinkedList会更有效。如何使用LinkedList创建和操作堆栈 请举个例子,不胜感激 Java的LinkedList是一个双链接列表,具有高效的访问器来获取、添加和删除列表末尾和开头的元素,因此您可以使用这些方法来模拟堆栈。LinkedList确实更高效,as堆栈由于依赖于向量,因此提供了同步方法。在单线程应用程序中,使用后者意味着付出同步代价而没有任何好处。即使在多线程应用程序中,也可能需要对同步进行

我正试图创建一个堆栈来获取一个字符串并将每个字符串字符添加到其中,但有人告诉我,使用LinkedList会更有效。如何使用LinkedList创建和操作堆栈


请举个例子,不胜感激

Java的LinkedList是一个双链接列表,具有高效的访问器来获取、添加和删除列表末尾和开头的元素,因此您可以使用这些方法来模拟堆栈。

LinkedList
确实更高效,as
堆栈
由于依赖于
向量
,因此提供了同步方法。在单线程应用程序中,使用后者意味着付出同步代价而没有任何好处。即使在多线程应用程序中,也可能需要对同步进行更多控制

这里有一个可能的基于LinkedList的解决方案。请注意使用组合而不是继承。这将为您提供一个性能良好的堆栈,该堆栈不能被使用列表相关方法滥用

class MyStack<T> {
    private List<T> list = new LinkedList<T>();

    public void push(T object) { list.add(0, object); }

    public T pop(T object) {
        if (isEmpty()) throw new NoSuchElementException();
        return list.remove(0);
    }

    public boolean isEmpty() { return list.isEmpty(); }
}
类MyStack{
私有列表=新的LinkedList();
公共无效推送(T对象){list.add(0,对象);}
公共T pop(T对象){
如果(isEmpty())抛出新的NoTouchElementException();
返回列表。删除(0);
}
公共布尔值isEmpty(){return list.isEmpty();}
}

尽管如此,如果堆栈如问题所示仅用于字符串,则可能需要直接在动态字符数组上模拟堆栈。我将把它作为练习留给读者,或者在以后的编辑中提供。

链接列表提供的操作比堆栈提供的操作更多

您可以使用堆栈来推送和弹出字符串中的字符。但是,只能按照与插入字符串的方式相反的顺序检索字符。所以你确定你想要这种行为吗

linkedlist允许您从head/tail添加/检索数据。

以下是示例:。希望能有帮助


这是用C完成的,但是你明白了,问题是你根本没有先使用
。请尝试以下操作:

public class Example
{
    private LinkedList aList = new LinkedList();

    public void push(char c) {
        aList.addFirst(c);
    }
    public Object pop() {
        return aList.removeFirst();
    }
    public boolean empty() {
        return aList.isEmpty();
    }
    public static void main(String[] args)  {
        Stack exmpStack = new Stack();
        String ranString = "Dad";
        for (int i = 0; i < ranString.length(); i++)  {
            exmpStack.push(ranString.charAt(i));
        }
        while (!exmpStack.empty())  {
            System.out.print(exmpStack.pop());
        }
    }
}
private LinkedList<Character> aList = new LinkedList<>();
现在这仍然有点不安全-您可以进一步使用以下方法:

public class Example
{
    private LinkedList aList = new LinkedList();

    public void push(char c) {
        aList.addFirst(c);
    }
    public Object pop() {
        return aList.removeFirst();
    }
    public boolean empty() {
        return aList.isEmpty();
    }
    public static void main(String[] args)  {
        Stack exmpStack = new Stack();
        String ranString = "Dad";
        for (int i = 0; i < ranString.length(); i++)  {
            exmpStack.push(ranString.charAt(i));
        }
        while (!exmpStack.empty())  {
            System.out.print(exmpStack.pop());
        }
    }
}
private LinkedList<Character> aList = new LinkedList<>();
private LinkedList=new LinkedList();

这样,它会更安全一些,返回
字符
s而不是
对象
——并且
字符
可以隐式转换为
字符
:)

更有效吗?为什么?@Thilo因为当我做“堆栈”时,我总是出错。Re:总是出错?当代码甚至不工作时,你怎么知道它是无效的?@Jay你不能在泛型中使用基元类型(char、int等)。尝试
Stack
。查看我的答案-立即发现问题:)始终发布您的代码。您能提供一个示例吗?我不确定代码会是什么样子啊,我知道这一点,我同意。我认为,如果需要堆栈,那么应该提供一个堆栈来支持封装原则。在堆栈中提供列表方法会导致错误,因为如果跳过堆栈的常规约定,堆栈可能会受到损害。@MihaiDanila你说得对。我误解了这个问题。看起来我给了一个关于家庭作业的高级答案。谢谢你的-1,伙计!不是我给了你-1,我感谢你的帮助。太棒了!非常感谢你!!您可能想从第二个示例中删除exmpStack。@DavidConrad说得对-谢谢,这让我有点困惑。。。。但我很感激你的投入!什么让人困惑?其思想是,始终将T添加为第一个节点,并始终从linkedlist中删除第一个节点