在使用Guava个集合并阅读其文档时,我一直在阅读 view 一词。
我已经在这个背景下寻找一个视图的解释,以及它是否是在番石榴之外使用的术语。它经常使用here。来自Guava的type名称中包含 view 。
我的猜测是,集合的视图是另一个具有相同数据但结构不同的集合;例如,当我将条目从java.util.HashSet
添加到java.util.LinkedHashSet
时,后者将是前者的视图。这是对的吗?
有人可以通过指向 view 的已接受定义的链接与我联系,如果有的话吗?
感谢。
答案 0 :(得分:19)
另一个对象的视图根本不包含自己的数据。它的所有操作都是根据对另一个对象的操作实现的。
例如,keySet()
的{{1}}视图可能具有如下所示的实现:
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)
将返回keySet.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
API访问普通数组; List
可让您访问Map.keySet()
的密钥,就好像它是完全普通的Map
- 所有,无需复制数据或创建其他数据结构。< / p>
通常,使用视图而不是制作副本的优点是效率。例如,如果您有一个数组,并且需要将其转换为采用Set
的方法,那么您不会创建新的List
和数据的完整副本 - {{ 1}}视图只占用常量额外内存,只需访问原始数组即可实现所有ArrayList
方法。
答案 1 :(得分:6)
此上下文中的视图是由另一个集合(或数组)支持的集合,该集合本身使用常量内存(即内存不依赖于后备集合的大小)。应用于视图的操作将委派给后备集合(或数组)。当然,可以将此定义扩展到仅仅是集合之外,但您的问题似乎与它们有关。
例如,Arrays.asList()
返回“指定数组的列表视图”。它不会将元素复制到新列表,而是创建一个包含对数组的引用的列表,并根据该列表进行操作。
另一个例子是Collections.unmodifiableList()
,它返回“指定列表的不可修改的视图”。换句话说,它返回一个列表,其中包含对委托所有操作的指定列表的引用。在这种情况下,返回的列表不允许您以任何方式修改它,因此,不是委托负责变更列表的方法,而是在调用此类方法时抛出异常。