Java 与具体类的接口 如果我们考虑下面两个实现,第一个实际使用是什么? List<String> a= new ArrayList<String>(); ArrayList<String> b= new ArrayList<String>();

Java 与具体类的接口 如果我们考虑下面两个实现,第一个实际使用是什么? List<String> a= new ArrayList<String>(); ArrayList<String> b= new ArrayList<String>();,java,design-patterns,arraylist,collections,interface,Java,Design Patterns,Arraylist,Collections,Interface,从我在文章中读到的内容来看,第一个实现有助于避免破坏更改,就像我们可以根据需要再次更改实现一样 a=new TreeList<String>(); 但我不明白用treelist更改实现的实际用途是什么,因为我们只能使用列表接口方法 但我不明白用treelist更改实现的实际用途是什么,因为我们只能使用列表接口方法 接口列表的不同实现对于不同的操作具有不同的性能特征。您应该选择列表的哪个实现不是任意的——不同的实现对于不同的目的更有效 例如,在中间的某个位置插入元素在数组列表上是昂贵

从我在文章中读到的内容来看,第一个实现有助于避免破坏更改,就像我们可以根据需要再次更改实现一样

a=new TreeList<String>();
但我不明白用treelist更改实现的实际用途是什么,因为我们只能使用列表接口方法

但我不明白用treelist更改实现的实际用途是什么,因为我们只能使用列表接口方法

接口列表的不同实现对于不同的操作具有不同的性能特征。您应该选择列表的哪个实现不是任意的——不同的实现对于不同的目的更有效

例如,在中间的某个位置插入元素在数组列表上是昂贵的,但在链接列表中很便宜,因为实现的方式是有效的。同样,通过索引访问元素在ArrayList上是便宜的,但在LinkedList上是昂贵的

当您开始编写程序时,可能会使用ArrayList而没有过多考虑它,但后来您发现LinkedList会更有效

当您根据接口列表而不是特定的实现进行编程时,很容易从ArrayList更改为LinkedList-对于程序的其余部分,它仍然看起来像一个列表,因此您只需更改一行。

树列表不存在,因此让我们以a为例

假设您有一个要保存到数据库的@实体:

public class MyMagicEntity {
    @OneToMany
    List<MyChildEntity> children;

    public void setChildren(final List<MyChildEntity> children) {
        this.children = children;
    }
}
因此,您创建了一个ArrayList,并将其传递到MyMagicEntity,MyMagicEntity会将其分配给列表,而不管底层实现是否是列表

现在,稍后您将执行以下操作:

final MyMagicEntity mme = //load from DB
final List<Children> children = mme.getChildren();
那么,什么是儿童?如果我们使用JPA和Hibernate,它实际上是一个PersistentList,而不是ArrayList

当我们访问孩子们的成员时,Hibernate将从数据库中取出他们。此列表仍然是一个列表-您的程序不必知道这些

您可以不使用列表界面来执行此操作吗?不因为:

无法创建PersistentList Hibernate无法创建ArrayList 虽然这是一个极端的例子,列表的基本行为完全不同,但这适用于所有其他情况

例如:

ArrayList和LinkedList具有不同的性能特征,您可能需要切换 番石榴有一个不可更改的列表,您可能想使用它 Collections.unmodifyableList还实现了您可能想要使用的列表 可以想象,您可以有一个文件支持的列表 基本思想是列表定义了任何列表必须能够做什么,而不是如何做

这里的List是一个接口,它包含了一个List可以执行的所有常用操作方法

列表接口是ArrayList、LinkedList和更多类的父类。因此,它可以保存所有这些类型的对象引用

所有这些列表方法都有不同的类型实现,或者使用不同的类实现自己的类型实现。所以,您使用的任何方法都将根据对象所属类的重写方法定义自动应用

List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
现在,在您的情况下,您可以声明两种方式都是正确的。但是假设这样一个场景

您正在调用一些服务,并且您知道返回的列表类型不是对象的特定类型。它可以是LinkedList、ArrayList或任何其他类型的列表

在那个时候,无论您得到什么样的响应,您都可以轻松地将这些响应保存在引用变量的列表类型中


在收集结果之后,您可以进一步区分对象类型。

假设您已经决定开发自己的更高效的列表实现。可能是一种内部内存管理更好的方法,或者可能是一种更快的set方法插入实现。您只需实现List接口,其余代码将继续工作,除了这一行之外,没有任何更改。您还可以扩展ArrayList并编写自己的代码

//Old code
List<String> a = new ArrayList<String>();
a.set(0, "Test");

//New code
List<String> a = new MyCustomisedList<String>();
//Same code, but your optimized set logic. May be faster...
a.set(0, "Test");

想想分类。ArrayList不会在添加时排序。其他实现可能会这样做。因此,如果需求更改为对项目进行排序,您只需交换实现,就完成了。您更改了客户机代码的行为,但没有更改其实现,只有一行选择了实现。当然:如果您需要使用特定于特定实现的方法,那么您必须使用该实现。非常感谢。。我现在明白了谢谢你的回答
//Old code
List<String> a = new ArrayList<String>();
a.set(0, "Test");

//New code
List<String> a = new MyCustomisedList<String>();
//Same code, but your optimized set logic. May be faster...
a.set(0, "Test");