【0】README

0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java集合——视图与包装器 的相关知识;
0.2) for full source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/ViewAndWrapper.java


1.1)通过使用视图可以获得其他的实现了集合接口和映射表接口的对象;

  • 1.1.1)视图定义:映射表类的keySet方法就是这样一个荔枝;keySet 方法返回一个实现了Set接口的类对象, 这个类的方法对原映射表进行操作, 这种集合称为视图;

1.2)集合框架中的遗留类图概览

1.3)轻量级集包装器

  • 1.3.1)Arrays类的静态方法asList 将返回一个包装了普通 java 数组的List 包装器。 这个方法可以将数组传递给一个期望得到列表或集合变元的方法, 例如:
Card[] cardDeck = new Card[25];
List<Card> cardList = Arrays.asList(cardDeck); (数组转List视图对象)

对以上代码的分析(Analysis):

  • A1)返回的对象不是 ArrayList。 它是一个视图对象, 带有访问底层数组的get和set方法;而改变该数组大小的所有方法(与迭代器相关的add 和 remove方法) 都会抛出一个UnsupportedOperationException 异常;
  • A2)asList方法: 它已经被声明为一个具有可变参数的方法, 除了可以传递一个数组外, 还可以将各个元素直接传递给这个方法:
List<String> names =  Arrays.asList<"a", "b", "c">;
  • A3)以上这个方法调用 Collections.nCopies(n , anObject) : 将返回一个实现了 List接口的不可修改对象, 并给人一种包含n个元素, 每个元素都是 Object的 错觉;
  • 1.3.2)看个荔枝:(干货——创建了 100个 DEFAULT, 由于字符串对象只存储了一次, 所以付出的存储代价很小, 这是视图技术的一种巧妙的应用)

List<String> settings = Collections.nCopies(100, "DEFAULT"); 

干货问题:(如何区分 Collection 和 Collections)

  • Anotation) Collections 类包含很多实用方法, 这些方法的参数和返回值都是集合。 不要将 Collection接口 和 Collections 包装类 混淆起来了;

  • 1.3.3)调用以下代码: Collections.singleton(anObject); 则返回一个视图对象。 这个对象实现了Set 接口。 返回的对象实现了一个不可修改的单元素集, 而不需要付出建立数据结构的 开销。 singletonList 和 singletonMap 方法类似;

    1.4) 子范围

  • 1.4.1)可以为很多集合建立子范围视图;
    如, List g2 = staff.subList(10,20); 从列表staff 中取出 第10个~第19个元素;(第一个 索引包含在内,第二个索引不包含在内)

  • 1.4.2)可以将任何操作应用到子范围, 并且能够自动地反应整个列表的情况;
    如, g2.clear(); 现在, 元素自动地从 staff 列表中清除了,并且g2 为空;
  • 1.4.3)对于有序集合映射表, 可以使用 排序顺序而不是元素位置建立子范围。

  • 1.4.3.1)SortedSet 接口说明了3个方法:

SortedSet<E> subSet(E from ,E to)
SortedSet<E> headSet(E to)
SortedSet<E> tailSet(E from)
  • 以上方法将返回 大于等于from 小于to的所有元素子集;
  • 1.4.3.2)有序映射表有类似方法:
SortedSet<E> subMap(E from ,E to)
SortedSet<E> headMap(E to)
SortedSet<E> tailMap(E from)
  • 返回映射表视图, 该映射表包含键落在指定范围内的所有元素;
  • 1.4.4) java SE6 引入的 NavigableSet 接口 赋予子范围操作更多 的控制能力。 可以指定是否包括边界:
NabigableSet<E> subSet(E from, boolean fromInclusive, E to, boolean toInclusive);
NabigableSet<E> headSet(E to, boolean toInclusive);
NabigableSet<E> tailSet(E from, boolean fromInclusive);


1.5)不可修改视图

  • Collections 还有几个方法, 用于产生集合的不可修改视图。 这些视图对现有集合增加了一个运行时的检查。 如果发现试图对集合进行修改, 就抛出一个异常, 同时这个集合将保持未修改状态;
    (再次提醒:注意区分 Collection 和 Collections)
  • 1.5.1)可以使用下列6种方法获得不可修改视图:
Collections.unmodifiableCollection
Collections.unmodifiableList
Collections.unmodifiableSet
Collections.unmodifiableSortedSet
Collections.unmodifiableMap
Collections.unmodifiableSortedMap
  • 每个方法都定义于一个接口。如, Collections.unmodifiableList 与 ArrayList、LinkedList 或者任何实现了 List接口的其他类一起协同工作;

  • 1.5.1荔枝):

List<String> staff = new LinkedList<>();
lookAt(Collections.unmodifiableList(staff)); // 返回一个不可修改视图, 传递给 loopAt方法;
  • Collections.unmodifiableList 方法返回一个实现List接口的类对象。当然,lookAt方法 可以调用 List 接口中的所有方法, 而不只是访问器。但是所有的更改器方法,已经被重新定义为 抛出一个 UnsuportedOperationException 异常,而不是 将调用传递给底层集合;
  • 1.5.2)不可修改视图并不是 集合本身不可修改 (干货——只是无法通过其投影出的视图修改原始集合)。 仍然可以通过集合的原始引用对集合进行修改。并且仍然可以让集合的元素调用更改方法;
  • 1.5.3)由于视图只是包装了 接口而不是 实际的集合对象, 所以只能访问 接口中定义的方法; 如, LinkedList 类有一些非常方便的方法, addFirst 和 addLast , 它们都不是 List接口的方法,不能通过修改视图进行访问;

Warning)

  • W1) unmodifiableCollection 方法将返回一个集合, 它的equals 方法不调用底层集合的equals 方法; 相反,它继承了 Object 类的 equals 方法, 该方法只是检测两个对象是否是同一个对象;
  • W2)如果将 集 或 列表转换成集合, 就再也无法检测其内容是否相同了, 视图就是以这种方式运行的, 因为内容是否相等的检测在分层结构的这一层上没有定义妥当;
  • W3)视图将以同样的方式处理 hashCode 方法;

1.6)同步视图

  • 1.6.1)如果由多个线程访问集合,就必须确保集不会被意外破坏, 类库的设计者使用视图及直接来确保常规集合的线程安全。
  • 1.6.2)例如, Collections 类的 静态 synchronizedMap 方法将任何一个映射表转换成具有同步访问方法的 Map:
Map<String, Employee> map = Collections.synchronizedMap(new HashMap<String, Employee>());

1.7)检查视图

  • 1.7.1)出现的问题:
ArrayList<String> strings = new ArrayList<>();
ArrayList rawList = strings;
rawList.add(new Date());//
  • 这个错误的 add 命令在运行时检测不到。 相反,只有在 调用 get方法, 并将其 转换为 String 时,这个类才会抛出一个异常;

  • 1.7.2)解决方法:检查视图可以探测到这类问题。下面定义了一个安全列表:
    List safeString = Collections.checkedList(strings, String.class);
    视图的add 方法将检测 插入的对象是否属于给定的类。 如果不属于给定的类, 就立即抛出一个 ClassCastException。 这样做的好处是错误可以在正确的位置得以报告:

ArrayList rawList = safeString;
rawList.add(new Date()); // checked list chrows a ClassCastException


Warning)

  • W1)被检测视图受限于 虚拟机可以运行的运行时检查。例如, 对于ArrayList

java集合——视图与包装器相关推荐

  1. Java包装器类及自动装箱(自动打包)

    1.为什么需要包装器类? Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便.例如,我们有时候需要将int这种基本类型转换为对象类型的,所有的 ...

  2. java类包装器有什么用_Java中的包装器类

    java类包装器有什么用 Wrapper class in java are the Object representation of eight primitive types in java. A ...

  3. Java集合知识概括

    Java集合知识概括 集合框架概述 Collection方法 Iterator迭代器接口 Collection子接口一:List Collection子接口二:Set Map接口 Collection ...

  4. Java集合框架概述及Collection接口方法讲解

    Java集合框架概述 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要对对象进行存储.另一方面,使用Array存储对象方面具有一些弊 端,而Java 集合就像一种容 ...

  5. java包装器类_Java中的基本类型和包装类

    Java中基本数据类型与包装类型有 基本类型 包装器类型 boolean Boolean char Character int Integer byte Byte short Short long L ...

  6. 《Java 核心技术卷1 第10版》学习笔记------ 对象包装器、自动装箱、拆箱

    有时, 需要将 int 这样的基本类型转换为对象. 所有的基本类型都冇一个与之对应的类.例如,Integer 类对应基本类型 int.通常, 这些类称为包装器 ( wrapper ) 这些对象包装器类 ...

  7. java是如何实现原语的_Java中的低GC:使用原语而不是包装器

    java是如何实现原语的 总览 有两个很好的理由在可能的地方使用原语而不是包装器. 明晰. 通过使用原语,您可以清楚地知道null值是不合适的. 性能. 使用原语通常更快. 清晰度通常比性能更重要,并 ...

  8. Java中的低GC:使用原语而不是包装器

    总览 有两个很好的理由在可能的地方使用原语而不是包装器. 明晰. 通过使用原语,您可以清楚地知道null值是不合适的. 性能. 使用原语通常更快. 清晰度通常比性能更重要,并且是使用它们的最佳理由. ...

  9. java hashedmap_Java基础 - Map接口的实现类 : HashedMap / LinkedHashMap /TreeMap 的构造/修改/遍历/ 集合视图方法/双向迭代输出...

    import java.util.*; /**一:Collection接口的 * Map接口: HashMap(主要实现类) : HashedMap / LinkedHashMap /TreeMap ...

最新文章

  1. python软件怎么使用-Python快速入门—如何选择使用包管理工具?
  2. php代码优化 -- array_walk 和 foreach, for 的效率的比较
  3. ArcGIS10.2 网络分析之路径分析(二)---构建网络数据集
  4. sql注入***原理
  5. hihocoder 1015 : KMP算法(kmp)
  6. 【并查集】【图论】【最小生成树】剑鱼行动(ssl 1618)
  7. bin文件如何编辑_如何为高通固件创建rawprogram0和patch0文件
  8. 使用VMWareWorkstation搭建学习环境
  9. 认识JWT(JSON WEB TOKEN)
  10. oracle ora 16014,ORA-16014 ORA-00312错误解决
  11. Java常用框架面试题
  12. 自动驾驶公司如何打造产品市场体系
  13. C语言定义结构体的几种方法
  14. 3 ROC曲线和PR曲线和AUG
  15. 打流工具trex使用
  16. 中控打卡机二次开发注册控件问题
  17. 如何选择适合你的兴趣爱好(六十六),折纸
  18. 基于 SpringBoot + Vue 框架开发的网页版聊天室项目
  19. SpringBoot服务启动无法访问localhost8080问题处理
  20. html的空格代码怎么写?教你如何使用空格nbsp代码

热门文章

  1. CF 1475 F . Unusual Matrix 思维
  2. bzoj5093: [Lydsy1711月赛]图的价值
  3. CF1550D Excellent Arrays(完全会了更新)
  4. G - Caesar Cipher Gym - 102798G
  5. P1232 [NOI2013] 树的计数
  6. jzoj1478-堆排序【堆】
  7. ACL Beginner Contest 总结——F多项式待补
  8. MongoDB新建或删除索引
  9. Dubbo(一)之简介
  10. 汇编语言(六)之输出字符的前导后字符