Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么要获取数据库';苹果';而不是ArrayList、Vector或LinkedList?_Java_Oop - Fatal编程技术网

Java 为什么要获取数据库';苹果';而不是ArrayList、Vector或LinkedList?

Java 为什么要获取数据库';苹果';而不是ArrayList、Vector或LinkedList?,java,oop,Java,Oop,我在一篇文章中看到了这样一个例子,不知道他们为什么这样做。假设您从一个数据库中获取了一组Apple对象: List<Apple> appleList = (List<Apple>) db.getApples() List appleList=(List)db.getApples() 为什么要强制转换为列表而不是具体的列表类型(ArrayList、Vector或LinkedList)?列表只是一个接口,而ArrayList或LinkedList是实现。根据Joshua

我在一篇文章中看到了这样一个例子,不知道他们为什么这样做。假设您从一个数据库中获取了一组Apple对象:

List<Apple> appleList = (List<Apple>) db.getApples()
List appleList=(List)db.getApples()

为什么要强制转换为
列表而不是具体的列表类型(ArrayList、Vector或LinkedList)?

列表
只是一个接口,而
ArrayList
LinkedList
是实现。根据Joshua Bloch-Effective Java(项目18;19),在这里使用接口总是更好的。因此,您可以轻松地切换实现。

大多数情况下,您不知道db所属API返回的列表的确切实现。它可能是Java SE中的标准实现之一,也可能是API的自定义实现。

方法
db.getApple()
的用户不应该关心这是否是
ArrayList
LinkedList
等。这是一个实现细节

在构造数据结构时,应该只指定数据结构的具体类型。之后,您应该参考适合您需要的界面


通过这种方式,您可以毫无困难地更改数据结构的具体类型。

通常使用公共接口是一种更好的方法。这样,底层实现就可以决定哪种具体类型最适合完成这项工作。它还使使用mock进行测试变得更容易。

和上的这篇wiki文章可能会帮助您理解为什么要对接口进行编程

在EE开发中常见的跨域工作时,您常常不关心使用的是哪种类型的集合。您通常不仅仅是想从中检索某些内容、对其进行迭代或删除某些内容。所有这些都不需要知道您正在处理的是哪种实现。它还可以轻松地切换出底层实现。例如,假设我正在处理一个项目,并将数据库中的项目列表加载到ArrayList中。在代码的其他地方,我将遍历以下列表:

class DBUtil {
    public static ArrayList<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}
类DBUtil{
公共静态数组列表getMeAllOfMyItems(){
返回项;//从数据库加载任何内容。。。
}
}
。。。同时

ArrayList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
LinkedList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (Item i : items) {
    // do something with item
}
arraylistitems=DBUtil.getMeAllOfMyItems();
对于(int i=0;i
现在让我们假设我决定使用链表代替。我必须更改从数据库加载所有内容的方法,以及用于迭代数据库的代码:

class DBUtil {
    public static LinkedList<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}
类DBUtil{
公共静态链接列表getMeAllOfMyItems(){
返回项;//从数据库加载任何内容。。。
}
}
。。。同时

ArrayList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
LinkedList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (Item i : items) {
    // do something with item
}
LinkedList items=DBUtil.getMeAllOfMyItems();
对于(int i=0;i
这是两个变化。如果我最初写的是:

class DBUtil {
    public static List<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}
class DBUtil {
    public static List<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}
类DBUtil{
公共静态列表getMeAllOfMyItems(){
返回项;//从数据库加载任何内容。。。
}
}
。。。同时

ArrayList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
LinkedList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (Item i : items) {
    // do something with item
}
List items=DBUtil.getMeAllOfMyItems();
对于(int i=0;i
我只需要更改一种方法,即从数据库返回项目的方法

更好的做法是更改迭代项目的方式,以便为每个样式使用:

类DBUtil{
公共静态列表getMeAllOfMyItems(){
返回项;//从数据库加载任何内容。。。
}
}
。。。同时

ArrayList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
LinkedList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}
List<Item> items = DBUtil.getMeAllOfMyItems();
for (Item i : items) {
    // do something with item
}
List items=DBUtil.getMeAllOfMyItems();
用于(项目i:项目){
//对这个项目做些什么
}
现在,如果我愿意,我甚至可以更改更多的实现,只要我使用的实现是Iterable,我甚至不在乎底层系统使用的是什么类型的集合


您应该努力使事情尽可能通用,不要因为其他地方的小更改而不得不更改3或4个文件

因为在Java中,您应该编写接口代码,而不是实现代码

这样做可以让库代码的作者选择最适合的列表实现,而您实际上并不在意。如果需要,则将列表复制到具有所需属性的列表实现中


例如,如果您需要O(1)个get时间,请复制到ArrayLIst。

完全不需要强制转换。@PartlyCloudy:如果不查看
db.getApple()
的样子,您怎么知道这是什么呢?@skaffman:这是一个扩展的引用转换,只要它引用
java.util.List