【问题标题】:Difference in LinkedList and ArrayList implementation? [duplicate]LinkedList 和 ArrayList 实现的区别? [复制]
【发布时间】:2011-11-10 07:54:01
【问题描述】:

可能重复:
When to use LinkedList<> over ArrayList<>?

我看到了 ArrayList 和 LinkedList 的 API,它似乎是一样的。除了它们的性能差异之外,在添加、删除和迭代列表方面也存在任何差异。

List arrList = new ArrayList();

List linList = new LinkedList();

ListarrList or linList 引用其实是实现了对应的类。这实际上意味着什么?

【问题讨论】:

标签: java


【解决方案1】:

就您的第一个问题而言:它们的性能和内存使用情况对您来说是唯一重要的差异(第三个,它们的实际实现细节,不是您关心的问题。)LinkedLists 使用更多内存,并且通过从头部遍历列表来获取第 22 个元素非常慢;但就在列表中间添加和删除元素而言,它们非常棒。 ArrayLists 使用更少的内存,并且获取第 22 个元素非常快——但是在中间插入或删除一个元素所花费的时间与列表的大小成正比。

就您的第二个问题而言:引用“实际实现列表”的说法是错误的,所以我真的不知道如何回答。引用变量是指实现List接口的对象;这两个类都实现了该接口,因此List 类型的引用可以引用任一类的对象。

【讨论】:

    【解决方案2】:

    ArrayList 由一个数组支持,该数组在需要时调整大小。 LinkedList 由元素节点组成,其引用指向前一个节点和下一个节点。这个网站上有很多讨论差异的帖子,只需搜索它们即可。

    【讨论】:

      【解决方案3】:

      Java 教程中对这两个 List 实现的优缺点进行了很好的讨论。请参阅List Implementations 上的主题。

      【讨论】:

        【解决方案4】:

        当您问“这实际上是什么意思?”时,我不能 100% 确定您的意思,但这是一个猜测。

        考虑这样的代码:

        interface Interface
        {
           void foo();
        }
        
        class Implementation
            implements Interface
        {
            public void foo() { }
            public void bar() { }
        }
        
        public class Main
        {
            public static void main(final String[] argv)
            {
                Interface a;
                Implementation b;
        
                a = new Implementation();
                b = a;
        
                a.foo();
                b.foo();
                a.bar(); <-  won't compile
                b.bar();
            }
        }
        

        接口a;和实施b;两者都指向同一个对象,但只有对“b”的引用才能访问“bar”方法。

        因此,在您的示例中,arrList 和 linList 都可以访问 List 接口中的任何方法,但它们提供的除了 List 接口之外的任何方法都不能在没有强制转换的情况下调用。您可以(并且在大多数情况下应该)将 ArrayList 和 LinkedList 视为一个列表。

        对于从不同列表中插入/添加/删除的细节,您通常不必关心。从最终结果的角度来看,两者的行为方式相同(例如,使用相同数据的相同方法调用序列将产生相同的结果,只是内部布局会有所不同)。

        【讨论】:

        • 你能详细解释一下接口 a 和 b 类是如何指向同一个对象的吗……我没听懂整行
        • a = new Implementation(); b = 一个;首先 a 被设置为 Implementation 的一个新实例,然后 b 指向同一个实例。有帮助吗?
        • 但只有对“b”的引用才能访问“bar”方法。为什么会这样????
        • 因为“a”被声明为不提供“bar”方法的接口。要让它工作,你必须让编译器知道它确实是一个实现实例 - ((Implementation)a).bar();所以即使“a”指向的对象有一个“bar”方法,编译器也不会让你直接调用它,因为它不在接口中。