黑马程序员技术交流社区

标题: subList函数 [打印本页]

作者: 冯鹏飞    时间: 2011-7-21 17:45
标题: subList函数
对于ArrayList  l=new ArrayList()而言,l.subList()返回值类型怎么会是List而非ArrayList 呢?该函数不是求其子集的吗?
作者: 王松朝    时间: 2011-7-21 18:06
subList()方法是接口List中定义的方法,返回值就是一个List类型,而ArrayList只是实现了List接口,本事并没有这个方法
作者: 匿名    时间: 2011-7-21 20:52
恩,LS说的很对!ArrayList本身没有提供subList这个方法,subList是List中的一个方法,但是Array实现了List接口!
ArrayList在JDK中的定义:[color=Red]Resizable-array implementation of the List interface.Implements all optional list operations, and permits all elements, including null.[/color] In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list.
作者: 王亮    时间: 2011-7-23 13:13
看了上面两位的回答,补充一下。
类实现接口,List有subList()方法(返回值为List),实现类完全可以实现它并且返回List的实现类的。就是说ArrayList的subList()方法是可能做到的(但是SUN没有这么做)。

而且ArrayList的subList是来继承自于AbstractList的(本身没有,是AbstractList实现的。而且ArrayList又实现了List)。List和AbstractList都有subList()方法(而且AbstractList实现了List,也(要说“也”,是因为AbstractList是抽象类,抽象类不实现接口的方法也可以)实现也subList方法,从下面的代码可以看出)
类树形结构:
java.lang.Object
  java.util.AbstractCollection<E>
      java.util.AbstractList<E>
        java.util.ArrayList<E>
我这样做[code=java] ArrayList list = new ArrayList();
转换异常:
java.util.RandomAccessSubList cannot be cast to java.util.ArrayList
所以subList返回的是RandomAccessSubList,奇怪?看源代码,因为ArrayList继承自AbstractList,而且也没有覆盖subList()方法,所以到AbstractList中找:

                list.add("wang");
                list.add("liang");
                list.add("hello world");
                ArrayList list2= (ArrayList) list.subList(0, 1);[/code]转换异常:
java.util.RandomAccessSubList cannot be cast to java.util.ArrayList

所以subList返回的是RandomAccessSubList,奇怪?看源代码,因为ArrayList继承自AbstractList,而且也没有覆盖subList()方法,所以到AbstractList中找:[code=java]public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<E>(this, fromIndex, toIndex) :
                new SubList<E>(this, fromIndex, toIndex));
}[/code]看到方法中又多出两个类RandomAccessSubList和SubList,它们在哪里?原来是和AbstractList类所在文件中(class SubList<E> extends AbstractList<E>,而class RandomAccessSubList<E> extends SubList<E> implements RandomAccess)
而ArrayList实现了RandomAccess,所以list.subList(0, 1)返回的是 RandomAccessSubList,显然不能转换。

List的实现类LinkedList也是类似,但是它没有实现RandomAccess,所以猜想上面的代码换成LinkedList也会出现异常,而且应该是SubList不能转换成LinkedList。[code=java]                LinkedList list = new LinkedList();
                list.add("wang");
                list.add("liang");
                list.add("hello world");
                LinkedList list2 = (LinkedList) list.subList(0, 1);[/code]确实java.util.SubList cannot be cast to java.util.LinkedList

为啥SUN将ArrayList的subList()的返回值搞成List?这是面现接口编程。List是个接口,不必关心子类(就是实现类)的具体行为。List只提供一个统一的“接口”(不是interface)就行了。面向接口编程似乎有人问了,网上也有资料,它的好处不是一两句话能说的清楚的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2