1、视图与包装器
Demo
Map<Integer,String> map = new HashMap<>();
map.put(1,"aaaaa");
map.put(2,"bbbbb");
map.put(3,"cccc");
System.out.println(map);
Set<Integer> keySet = map.keySet();
System.out.println("键"+keySet);
// keySet.add(4);//通过视图向map中添加新的键;Exception in thread "main" java.lang.UnsupportedOperationException
//通过视图向map中删除某个键‘
keySet.remove(1);
System.out.println(map);
2、轻量级集合包装器
Arrays类的静态方法
asList
将返回一个包装了普通Java数组的List
包装器。这个方法可以降数组传递给一个期望得到的列表或集合参数的方法:
String[] strings = new String[5];
strings[0]="1";
strings[1]="2";
strings[2]="3";
strings[3]="4";
strings[4]="5";
//返回得到的对象不是ArrayList
//它是一个视图对象,带有访问底层数组的get和set方法。
//该边数组大小的所有方法(例如,与迭代器相关的add和remove)都会抛出一个Unsupported OperationException
List<String> list = Arrays.asList(strings);
list.add("111");
private static class ArrayList<E> extends AbstractList<E>
在Arrays
内部定义;继承了AbstractList
在AbstractList内部没有实现
add
,remove
方法;在ArrayList
内部同样没有实现这些方法,因此这些方法直接从AbstractList
内部直接继承
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
3、子范围
可以为很多集合建立
子范围(subrange
)视图
- 对于
有序集
和映射
,可以使用排序顺序而不是元素位置
建立子范围SortedSet接口声明了3个方法:
subSet(E from,E to)
headSet(E to)
tailSet(E from)
这些方法将返回大于等于
from
且小于to
的所有元素子集有序映射也有类似的方法:
SortedMap< K, V> subMap(K from, K to)
SortedMap<K, V> headMap(K to)
So「tedMap<K, V> tail Map(K from)
返回映射视图,该映射包含
键
落在指定范围内的所有元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
//在视图中的操作等同于在原队列中的操作
List<Integer> newList = list.subList(0,5);
newList.add(6);
System.out.println(list);
System.out.println(newList);
4、不可修改视图
Collections
还有几个方法,用于产生集合的不可修改视图(unmodifiable views)
这些视图对现有集合增加了一个运行时的检查。
如果发现视图对集合进行修改,就抛出一个异常,同时这个集合将保持未修改的状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3F4vCHwB-1580979095546)(images/18.png)]
5、同步视图
如果由多个线程访问集合,就必须确保集不会被意外地破坏。
例如, 如果一个线程试图将元素添加到散列表中,同时另一个线程正在对散列表进行再散列,其结果将是灾难性的 .
类库的设计者使用视图机制来确保常规集合的线程安全, 而不是实现线程安全的集合类。例如,
Collections
类的静态synchronizedMap
方法可以将任何一个映射表转换成具有同步访问方法的Map
:Map<String, Employee〉map = Collections.synchronizedMap(new HashMap<String, Employee>0;)
现在,就可以由多线程访问
map
对象了 。像get
和put
方法都是同步操作的
;即在另一个线程调用另一个方法之前,刚才的方法调用必须彻底完成
6、关于可选操作的说明
通常,视图有一些局限性,即可能只能读、无法改变大小、只支持删除而不支持插入;
这些与映射的键视图情况相同。
如果视图进行不恰当的操作,受限制的视图就会抛出一个
UnsupportedOperationException``