当前位置: 首页 > news >正文

[改善Java代码]子列表只是原列表的一个视图

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

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 public class Client {
 5     public static void main(String[] args) {
 6         //定义一个包含两个字符串的列表
 7         List<String> c = new ArrayList<String>();
 8         c.add("A");
 9         c.add("B");    
10         //构造一个包含c的字符串列表
11         List<String> c1 = new ArrayList<String>(c);
12         //通过subList生成与c相同的列表
13         List<String> c2 = c.subList(0, c.size());
14         //c2增加一个元素
15         c2.add("C");        
16         System.out.println("c == c1? " + c.equals(c1));
17         System.out.println("c == c2? " + c.equals(c2));
18         
19     }
20 }

程序输出:

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

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

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

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

1 public class Client {
2     public static void main(String[] args) {
3         String str = "AB";
4         String str1 = new String(str);
5         String str2 = str.substring(0) + "C";
6         System.out.println("str == str1 " + str.equals(str1));
7         System.out.println("str == str2 " + str.equals(str2));
8     }
9 }

输出结果:

str == str1 true
str == str2 false

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

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

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

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

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产生的列表只是一个视图,所有的修改动作直接作用于原列表.

 

转载于:https://www.cnblogs.com/DreamDrive/p/5660044.html

相关文章:

  • 使用Java自带SAX工具解析XML
  • 使用SAX解析XML (控制台程序)
  • PMI列子1
  • 一个简单实用的AJAX例子
  • VS使用技巧
  • 一个最简单的AJAX实例及解析
  • 静态库中有图片,改如何存放呢??
  • 用Java结合SAX 2.0 解析XML文档
  • HDU 2594 Simpsons’ Hidden Talents(辛普森一家的潜在天赋)
  • 在Dom4j中使用xpath
  • C# 文件与目录的基本操作(System.IO)
  • 在JavaScript中使用Java
  • Postgresql 同步流复制
  • ??在JSP中,java和JavaScript如何交互?
  • 在Struts应用中使用Ajax
  • [笔记] php常见简单功能及函数
  • __proto__ 和 prototype的关系
  • 345-反转字符串中的元音字母
  • Angular数据绑定机制
  • bearychat的java client
  • emacs初体验
  • k个最大的数及变种小结
  • Nacos系列:Nacos的Java SDK使用
  • python docx文档转html页面
  • Python打包系统简单入门
  • Spring声明式事务管理之一:五大属性分析
  • SQLServer之创建数据库快照
  • 不上全站https的网站你们就等着被恶心死吧
  • 深度学习入门:10门免费线上课程推荐
  • PostgreSQL之连接数修改
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • ​用户画像从0到100的构建思路
  • #、%和$符号在OGNL表达式中经常出现
  • (003)SlickEdit Unity的补全
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (十)c52学习之旅-定时器实验
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (原創) 未来三学期想要修的课 (日記)
  • (转)ObjectiveC 深浅拷贝学习
  • .naturalWidth 和naturalHeight属性,
  • .net core 6 集成和使用 mongodb
  • .NET CORE Aws S3 使用
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET Core中Emit的使用
  • .Net IOC框架入门之一 Unity
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET 使用配置文件
  • .NET/C# 的字符串暂存池
  • .net快速开发框架源码分享
  • .NET连接数据库方式
  • .net中我喜欢的两种验证码