美文网首页
集合视图(Views)

集合视图(Views)

作者: 爱做梦的严重精神病患者 | 来源:发表于2019-03-11 14:31 被阅读0次

  视图(Views),简单的说就是具有限制的集合对象
  通过使用视图(Views)可以获得其他的实现了Collection接口和Map接口的对象。映射类的keySet方法就是一个这样的示例。keySet方法返回一个实现Set接口的类对象,这个类的方法可以对原映射进行操作。

  视图技术在集合框架中有许多非常有用的应用

1.轻量级集合包装器

  Arrays类静态方法asList返回一个包装了普通Java数组的List包装器

Card[] cardDeck = new Card[52];
...
List<Card> cardList = Arrays.asList(cardDeck);

  返回的对象不是ArrayList。它是一个视图对象带有访问底层数组的get和set方法改变数组大小的所有方法都会抛出一个异常

2.子范围

  可以为很多集合建立子范围视图。例如一个列表staff,想从中取出第10个~第19个元素。可以使用subList方法来获得一个列表的子范围视图

List group = staff.subList(10, 20);

  对于有序集和映射可以使用排序顺序而不是元素位置建立子范围。下面这些方法将返回大于等于from且小于to的所有元素子集。

SortedSet<E> subSet(E from, E to)
SortedSet<E> headSet(E to)
SortedSet<E> tailSet(E from)

  返回映射视图,该映射包含键落在指定范围内的所有元素。

SortedMap<K, V> subMap(K from, K to)
SortedMap<K, V> headMap(K to)
SortedMap<K, V> tailMap(K from)

  Java SE 6引入的NavigableSet接口赋予子范围操作更多的控制能力

3.不可修改的视图

  Collections还有几个方法,用于产生集合的不可修改视图(unmodifiable views)。这些视图对现有集合增加了一个运行时的检查。如果发现试图对集合进行修改,就抛出一个异常,同时这个集合将保持未修改的状态。
  可以使用下面8中方法获得不可修改视图:

//每个方法定义于一个接口
Collections.unmodifiableCollection
Collections.unmodifiableList
Collections.unmodifiableSet
Collections.unmodifiableSortedSet
Collections.unmodifiableNavigableSet
Collections.unmodifiableMap
Collections.unmodifiableSortedMap
Collections.unmodifiableNavigableMap

  例如,想要查看某部分代码,但又不触及某个集合的内容,就可以进行下列操作

List<String> staff = new LiskedList<>();
...
lookAt(Collections.unmodifiableList(staff));

  Collections.unmodifiableList方法返回一个实现List接口的类对象。其访问器方法将从staff集合中获取值。当然,lookAt方法可以调用List接口中的所有方法,而不只是访问器。但是所有的更改器方法已经被重新定义为异常,而不是将调用传递给底层集合。
  由于视图只是包装了接口,而不是实际的集合对象,所以只能访问接口中定义的方法例如LinkedList类中有一些非常方便的方法,addFirst和addLast,他们都不是List接口的方法不能通过不可修改视图进行访问

4.同步视图

  如果由多个线程访问集合,就必须确保集合不会被意外地破坏。类库的设计者使用视图机制确保常规集合的线程安全,而不是实现线程安全的集合。例如,Collections类的静态synchronizedMap方法可以任何一个映射表转换成具有同步访问方法的Map

Map<String, Employee> map = Collections.synchronizedMap(new HashMap<String, Employee>());

  现在,就可以由多线程访问map对象了。像get和put这类方法都是同步操作的,即在另一个线程调用另一个方法之前,刚才的方法调用必须彻底完成。

5.受查视图

  “受查”视图用来对泛型类型发生问题时提供调试支持

ArrayList<String> strings = new ArrayList<>();
ArrayList rawList = strings;
rawList.add(new Date());//Error

  这个错误的add命令在运行时检测不到。相反,只有在稍后的另一部分代码中调用get方法,并将结果转化为String时,才会抛出异常。

  受查视图可以探测到这类问题。

List<String> safeStrings = Collections.checkedList(strings, String.class);

  视图的add方法将检测插入的对象是否属于给定的类。

相关文章

网友评论

      本文标题:集合视图(Views)

      本文链接:https://www.haomeiwen.com/subject/opyvpqtx.html