另一个对象的视图根本不包含它自己的数据。它的所有操作都是根据对另一个对象的操作来实现的。
例如,a 的keySet()
视图Map
可能有一个看起来像这样的实现:
class KeySet implements Set<K> {
private final Map<K, V> map;
public boolean contains(Object o) {
return map.containsKey(o);
}
...
}
特别是,每当您修改视图的支持对象(此处为Map
支持对象)时,keySet()
视图都会反映相同的更改。例如,如果您调用map.remove(key)
, thenkeySet.contains(key)
将返回false
而无需您执行任何其他操作。
或者,Arrays.asList(array)
提供List
该数组的视图。
String[] strings = {"a", "b", "c"};
List<String> list = Arrays.asList(strings);
System.out.println(list.get(0)); // "a"
strings[0] = "d";
System.out.println(list.get(0)); // "d"
list.set(0, "e");
System.out.println(strings[0]); // "e"
视图只是查看原始支持对象中数据的另一种方式——Arrays.asList
允许您使用List
API 访问普通数组;Map.keySet()
让您可以像访问Map
一个完全普通的 a 一样访问它的键Set
——所有这些都无需复制数据或创建另一个数据结构。
通常,使用视图而不是复制的优点是效率。例如,如果您有一个数组,并且您需要将它获取到一个采用 a 的方法List
,那么您并没有创建一个新ArrayList
的和完整的数据副本——Arrays.asList
视图只占用恒定的额外内存,并且只是实现了所有List
通过访问原始数组的方法。