List接口提供了subList方法,其作用是返回一个列表的子列表.这与String类的subString有点类似.但是他们的功能是否相同?看代码:

 import java.util.ArrayList;
import java.util.List; public class Client {
public static void main(String[] args) {
//定义一个包含两个字符串的列表
List<String> c = new ArrayList<String>();
c.add("A");
c.add("B");
//构造一个包含c的字符串列表
List<String> c1 = new ArrayList<String>(c);
//通过subList生成与c相同的列表
List<String> c2 = c.subList(0, c.size());
//c2增加一个元素
c2.add("C");
System.out.println("c == c1? " + c.equals(c1));
System.out.println("c == c2? " + c.equals(c2)); }
}

程序输出:

c == c1? false
c == c2? true

c1是通过ArrayList的构造函数创建的,c2是通过列表的subList方法创建的,然后c2又增加了一个元素C,现在的问题是输出的结果是什么呢?

列表c与c1,c2之间是什么关系呢?

别忙着回答这个问题,回想一下String类的subString方法,看看它是如何工作的.

 public class Client {
public static void main(String[] args) {
String str = "AB";
String str1 = new String(str);
String str2 = str.substring(0) + "C";
System.out.println("str == str1 " + str.equals(str1));
System.out.println("str == str2 " + str.equals(str2));
}
}

输出结果:

str == str1 true
str == str2 false

很明显str与str1是相等的(虽然不是同一个对象,但用equals方法判断是相等的),但它们与str2不相等,这也毋庸置疑,因为str2在对象池中重新生成了一个新的对象,其值是ABC,那当然与str和str1不相等了.

为什么subList的结果正好好subString的相反?

c2是通过subList方法从c列表中生成了 一个子列表,然后c2又增加了一个元素,可为什么增加了 一个元素还会相等呢?看subList的源码:

     public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}

subList方法由AbstractList实现的,它会根据是不是可以随机存取来提供不同的SubList实现方式,不过,随机存储的使用频率比较高,而且RandomAccessSubList也是SubList子类,所以所有的操作都是由SubList类实现的(除了自身的SubList方法外),

看SubList的源码:

通过阅读这段代码,就非常清楚的subList方法的实现原理了:它返回的SubList类也是AbstractList的子类,其所有的方法如get,set,add,remove等都是在原始列表上的操作,它自身并没有生成一个数组或是链表,也就是子列表只是原始列表的一个视图(View),所有的修改动作都反映在了原列表上....

我们例子中的c2增加了一个元素C,不过增加的元素C到了c列表上,两个变量的元素仍然保持完全一致,相等也就很自然了.

为什么c和c1不相等.因为通过ArrayList构造函数创建的List对象c1实际上是新列表,它是通过数组的copyOf动作生成的,所生成的列表c1与原列表c之间没有任何关系(虽然是浅拷贝,但元素类型是String,也就是说元素是深拷贝的),

然后c又增加了元素,因为c1与c之间已经没有任何的关系了,自然不相等.

subList产生的列表只是一个视图,所有的修改动作直接作用于原列表.

[改善Java代码]子列表只是原列表的一个视图的更多相关文章

  1. [改善Java代码]不同的列表选择不同的遍历方法

    一.场景: 我们来看一个场景,统计一个省的各科高考科目考试的平均分. 当然使用数据库中的一个SQL语句就能求出平均值,不过这个不再我们的考虑之列,这里只考虑使用纯Java的方式来解决.(由于我的机器配 ...

  2. [改善Java代码]避开基本类型数组转换列表陷阱

    开发中经常用到Arrays和Collections这两个工具类. 在数组和列表之间进行切换.非常方便.但是也会遇到一些问题. 看代码: import java.util.Arrays; import ...

  3. [改善Java代码]asList方法产生的List对象不可更改

    上一个建议之处了asList方法在转换基本类型数组时候存在的问题,在看下asList方法返回的列表有何特殊的地方.看代码: import java.util.Arrays; import java.u ...

  4. [改善Java代码]推荐在复杂字符串操作中使用正则表达式

    一.分析  字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...

  5. [改善Java代码]推荐使用String直接量赋值

    建议52:推荐使用String直接量赋值 一.建议 String对象的生成方式有两种: 1.通过new关键字生成,String str3 = new String(“中国”); 2.直接声明,如:St ...

  6. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  7. [改善Java代码]不推荐使用binarySearch对列表进行检索

    对一个列表进行检索时,我们使用的最多的是indexOf方法,它简单好用,而且也不会出错,虽然它只能检索到第一个符合条件的值,但是我们可以生成子列表后再检索.这样也就可以查找到所有符合条件的值了. Co ...

  8. [改善Java代码]列表相等只需关系元素数据

    来看一个判断列表相等的例子,看代码: import java.util.ArrayList; import java.util.Vector; public class Client { public ...

  9. [改善Java代码]数组的真实类型必须是泛型类型的子类型

    List接口的toArray方法可以把一个结合转化为数组,但是使用不方便,toArray()方法返回的是一个Object数组,所以需要自行转变. toArray(T[] a)虽然返回的是T类型的数组, ...

随机推荐

  1. Java邮件服务学习之二:SMTP和POP3

    一.SMTP SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则.SMTP协议属于TCP/IP协议簇,它帮助每台计算 ...

  2. Java集合之ArrayList和LinkedList的实现原理以及Iterator详解

    ArrayList实现可变数组的原理: 当元素超出数组内容,会产生一个新数组,将原来数组的数据复制到新数组中,再将新的元素添加到新数组中. ArrayList:是按照原数组的50%来延长,构造一个初始 ...

  3. C++问题-无法打开某个自定义源文件

    问题经过:需要做一个工具,是在某个产品的基础上做的,所以要来了同事的代码.用VS打开后,提示如下问题.1>c1xx : fatal error C1083: 无法打开源文件:“..\..\GUX ...

  4. HIVE删除表数据

    HIVE只有INSERT,没有UPDATE跟DELETE,所以通过其他的语句产生DETELE效果. 在HDFS上或者本地服务器上新建空的文件XXXXX, 然后执行: LOAD DATA LOCAL I ...

  5. UVA 796 - Critical Links (求桥)

    Critical Links  In a computer network a link L, which interconnects two servers, is considered criti ...

  6. css知识汇总

    <style type="text/css"> table{ border-collapse:collapse; } table, td, th{ border:1px ...

  7. HDU 5768 Lucky7 (中国剩余定理+容斥)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768 给你n个同余方程组,然后给你l,r,问你l,r中有多少数%7=0且%ai != bi. 比较明显 ...

  8. Java学习笔记(一):数据类型与变量

    数据类型 Java中存在2种数据类型,下面我们来详解一下: 基本数据类型: 引用数据类型: 可以用一张表来记录: 基本数据类型 整型 byte:1个字节8位,取值范围为:[-128, 127],直接写 ...

  9. 使用WinDbg获得托管方法的汇编代码

    概述:有时候,我们需要查看一个托管方法的汇编指令是怎么样的.记得在大学的时候,我们使用gcc -s和objdump来获得一个c程序代码的汇编指令.但是对于.NET程序来说,我们肯定无法轻松地获得这些内 ...

  10. Educational Codeforces Round 1 A. Tricky Sum 暴力

    A. Tricky Sum Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/598/problem ...