java集合——视图与包装器

【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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php把表单转为json保存,javascript – 使用jquery将表单数据保存到本地json文件中

我有一个带有一些输入字段的基本表单.我想在提交表单时将表单数据保存到json文件中.json文件中保存数据的格式应如下所示.[{"title":"some text","description":"some text","info":"some text","username&q…

java之包装类与BigInteger、BigDecimal

一、包装类 &#xff08;1&#xff09;包装类与原类型 Integer int 的包装类 Boolean boolean 的包装类 Character char的包装类 Double double的包装类 Float float 的包装类 Byte …

哈希值 哈希表_哈希杰森

哈希值 哈希表我最近写了一个简单的库&#xff0c;可预测地对json进行哈希处理 。 该实用程序基于出色的Jackson Json解析库构建 问题 我需要从相当大的基于json的内容生成的哈希值&#xff0c;以便稍后确定该内容是否发生了更改。 将json视为字符串不是格式化的选项&#xf…

新浪微博搜索php待遇,新浪微博面试

PHP技术基础1、合并数据的函数。我当时回答的是array_merge()&#xff0c;array_combine()(注意与前者的区分);当时面试官告诉我还可以使用 加号()2&#xff0c;判断一个IP地址是否合法。只让说一下思路&#xff1a;(1)用点分割.&#xff0c;$arrIp explore()&#xff1b;(2)判…

java集合——集合与数组间的转换+算法

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码为原创&#xff0c;旨在理解 java集合——集合与数组间的转换算法 的相关知识&#xff1b; 0.2&#xff09; for full source code , please visit https://github.com/pacosonTang/core-jav…

java之String

一、String类的特性 String对象是不可变的&#xff0c;字符串一旦创建&#xff0c;就不可以改变。二、构造字符串字符串直接量String anew String("字符串直接量"); 字符数组String bnew String(chars);字符串直接量赋值&#xff0c;java把字符串直接量看作String对象…

java记录目录树_Java记录

java记录目录树https://openjdk.java.net/jeps/359概述了Java的新功能&#xff0c;该功能可能会/将在某些将来的Java版本中实现。 JEP建议使用一种新的“类别”&#xff1a;记录。 JEP中的示例内容如下&#xff1a; record Range( int lo, int hi) { public Range { if (lo >…

java集合——遗留的集合

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码为原创&#xff0c;旨在理解 java集合——遗留的集合 的相关知识&#xff1b; 0.2&#xff09; for full source code , please visit https://github.com/pacosonTang/core-java-volume/blo…

oracle 扩展分区,Oracle 在线扩展分区

在对Oracle分区表操作是&#xff0c;当一个分区已经有了最大的分区&#xff0c;如何再次扩展分区呢&#xff1f;简单的方式是先删除最大分区&#xff0c;然后添加需要的分区在对Oracle分区表操作是&#xff0c;当一个分区已经有了最大的分区&#xff0c;如何再次扩展分区呢&…

java之StringBuider与StringBuffer

一、StringBuider与StringBuffer StringBuider与StringBuffer类比String更加灵活&#xff0c;只要使用字符串的地方&#xff0c;都可以使用StringBuider与StringBuffer类。三者的共同之处都是 final 类&#xff0c;不允许被继承&#xff0c;这主要是从性能和安全性上考虑的&…

织机原理_项目织机

织机原理为什么为什么&#xff1f; Java 8流背后的驱动程序之一是并发编程。 在流管道中&#xff0c;指定要完成的工作&#xff0c;然后任务将自动分配到可用处理器上&#xff1a; var result myData.parallelStream().map(someBusyOperation).reduce(someAssociativeBinOp)…

java集合——java.util.Properties类

【0】README 0.1&#xff09;以下全文转自 &#xff1a;  http://trans.blog.51cto.com/503170/110227/ 【1】认识properties文件 1、 properties文件是一个文本文件2、 properties文件的语法有两种&#xff0c;一种是注释&#xff0c;一种属性配置。 注 释&#xff1a;前…

电力系统潮流计算matlab程序,大神们,求个电力系统潮流计算的matlab程序。

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼ninput(Please input n\n); %n表示系统的节点数d0input(Please input d0\n); %d0表示系统的误差minput(Please inpit m\n); %m表示系统的pq节点的个数p0ones(n-1,1);q0ones(m,1);d1;dpvones(n-1,1);dqvones(m,1);dpzeros(n-1,1);dq…

java之正则表达式

一、匹配字符串String类的matchs方法用的是正则表达式匹配&#xff0c;matchs方法与equals类似。"javac".matchs("javac");"javac".equals("javac");结果都为true。match方法更强大&#xff0c;不仅能匹配固定字符串&#xff0c;还能匹…

gradle配置_Gradle配置

gradle配置在这篇文章中&#xff0c;我们将介绍有关Gradle配置的综合文章。 1.技术 Gradle是用于自动任务管理的开源构建工具。 它基于Apache Ant&#xff0c;Apache Maven的概念。 Gradle是使用Groovy语言开发的。 Gradle是使用基于Groovy的领域特定语言&#xff08;DSL&…

removeAll throws java.lang.UnsupportedOperationException

【1】出现的问题&#xff1a; 如果该列表list 不支持 removeAll 方法的话&#xff0c; 就会抛出UnsupportedOperationException 【2】解决方法&#xff1a; List<String> list new ArrayList(Arrays.asList(new String[]{"C","B","D"})…

C#的float、double与decimal

float 单精度浮点 32bit&#xff0c;double 双精度浮点64bit&#xff0c;decimal是高精度 128bit&#xff0c;浮点型。 float double 是 基本类型&#xff08;primitive type&#xff09;&#xff0c;decimal不是。 float 有效数字7位&#xff0c;范围 1.5 10E−45 to 3.4 …

matlab支持 编程语言,用于数学的10个优秀编程语言

原标题&#xff1a;用于数学的10个优秀编程语言译文&#xff1a;http://www.codeceo.com/article/10-programming-language-for-math.html英文&#xff1a;10 Great Programming Languages for Mathematics翻译&#xff1a;码农网 – 小峰作为一个对数学和编程语言充满激情的人…

java锁_Java锁

java锁锁是一种线程同步机制&#xff0c;例如同步块。 锁是使用同步块在内部实现的。 因此&#xff0c;我们可以在Java中使用锁代替同步关键字。 锁比同步块更灵活&#xff0c;更复杂。 从Java 5版本开始&#xff0c;JDK提供了几种锁实现&#xff0c;例如ReentrantReadWriteLo…

java线程——阻塞队列

【0】README 0.1&#xff09;本文均转自两篇网络文章&#xff0c; 转载地址在转载处做了标记&#xff0c; 旨在理清 “阻塞队列”的相关知识 &#xff1b; 【1】转自&#xff1a; http://www.cnblogs.com/dolphin0520/p/3932906.html 1.1&#xff09;在前面我们接触的队列都是…