另一个对象的视图根本不包含它自己的数据。它的所有操作都是根据对另一个对象的操作来实现的。
例如,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允许您使用ListAPI 访问普通数组;Map.keySet()让您可以像访问Map一个完全普通的 a 一样访问它的键Set——所有这些都无需复制数据或创建另一个数据结构。
通常,使用视图而不是复制的优点是效率。例如,如果您有一个数组,并且您需要将它获取到一个采用 a 的方法List,那么您并没有创建一个新ArrayList的和完整的数据副本——Arrays.asList视图只占用恒定的额外内存,并且只是实现了所有List通过访问原始数组的方法。