ArrayList <integer> list = new ArrayList <integer>()之间的区别;和集合<integer> list1 = new ArrayList <integer>(); </integer> </integer> </integer> </integer>

时间:2013-01-04 19:06:34

标签: java

我不明白这些事情之间的区别:

ArrayList<Integer> list = new ArrayList<Integer>();Collection<Integer> list1 = new ArrayList<Integer>();

ArrayList扩展了实现接口Collection的类,因此类ArrayList实现了Collection接口。也许list1允许我们使用Collection接口中的静态方法?

5 个答案:

答案 0 :(得分:12)

接口没有静态方法[在Java 7中]。 list1仅允许访问Collection中的方法,而list则允许访问ArrayList中的所有方法。


最好声明具有最小特定可能类型的变量。因此,例如,如果您因任何原因将ArrayList更改为LinkedListHashSet,则无需重构代码的大部分内容(例如,客户端类)。 / p>

想象一下你有这样的东西(仅用于说明目的,不可编译):

class CustomerProvider {
    public LinkedList<Customer> getAllCustomersInCity(City city) {
        // retrieve and return all customers for that city
    }
}

然后你决定实现它返回HashSet。也许有一些客户端类依赖于您返回LinkedList这一事实,并调用HashSet没有的方法(例如LinkedList.getFirst())。

这就是你最好这样做的原因:

class CustomerProvider {
    public Collection<Customer> getAllCustomersInCity(City city) {
        // retrieve and return all customers for that city
    }
}

答案 1 :(得分:2)

我们在这里处理的是界面实施之间的区别。

接口是一组方法,不考虑这些方法的实现方式。当我们将一个对象实例化为一个实际上是interface的类型时,我们所说的是它是一个实现interface中所有方法的对象......但是没有提供可以访问实际提供这些实现的class中的任何方法。

当您实例化具有实施class类型的对象时,您可以访问该class的所有相关方法。由于class正在实现interface,因此您可以访问界面中指定的方法,以及实现类提供的任何额外内容。

你为什么要这样做?好吧,通过将对象的类型限制为interface,您可以切换新的实现,而无需担心更改其余代码。这使它变得更加灵活。

答案 2 :(得分:2)

与其他人所说的不同之处在于,当您将其指定为变量类型时,仅限于Collection接口定义的方法。但这并没有回答你为什么要这样做的问题。

原因是数据类型的选择使用代码向人们提供信息。特别是当从函数中用作参数或返回类型时(外部程序员可能无法访问内部函数)。

为了达到特异性,以下是不同类型选择可能告诉您的内容:

  • Collection - 一组对象,没有进一步的保证。此对象的使用者可以遍历集合(不保证迭代顺序),并且可以了解其大小,但不能执行任何其他操作。
  • List - 一组具有特定订单的对象。当您遍历这些对象时,您将始终以相同的顺序获取它们。您还可以通过索引从集合中检索特定项目,但不能对此类检索的性能做出任何假设。
  • ArrayList - 一组具有特定顺序的对象,可以在固定时间内通过索引访问。

虽然你没有问过它们,但这里有一些其他的集合类:

  • Set一组对象,保证每个equals()方法不包含重复项。无法保证这些对象的迭代顺序。
  • SortedSet一组不包含重复项的对象,并且将始终以特定顺序迭代(尽管该集合无法保证该特定顺序)。
  • TreeSet一组没有重复的有序对象,展示O(logN)插入和检索时间。
  • HashSet一组没有重复的对象,没有固有的顺序,但提供(摊销的)恒定时间访问。

答案 3 :(得分:1)

唯一的区别是您通过Collection接口提供对list1的访问,而您通过ArrayList接口提供对list2的访问。有时,通过受限制的接口提供访问非常有用,因为它可以促进封装并减少对​​实现细节的依赖。

答案 4 :(得分:0)

当您对“list1”执行操作时,您将只能访问Collection接口中的方法(get,size等)。通过将“list”声明为ArrayList,您可以访问仅在ArrayList类中定义的其他方法(例如,ensureCapacity和trimToSize。

通常最佳做法是将变量声明为您需要的最不具体的类。因此,如果您只需要Collection中的方法,请使用它。通常在这种情况下,这意味着使用List,它可以让您知道它的有序并且可以处理重复。

使用最不具体的类/接口允许您稍后自由更改实现。例如,如果您稍后了解到LinkedList是一个更好的实现,那么如果您将变量定义为List,则可以在不破坏所有代码的情况下更改它。