什么是集合的视图?

时间:2013-09-19 18:37:46

标签: java collections guava

在使用Guava个集合并阅读其文档时,我一直在阅读 view 一词。

我已经在这个背景下寻找一个视图的解释,以及它是否是在番石榴之外使用的术语。它经常使用here。来自Guava的type名称中包含 view

我的猜测是,集合的视图是另一个具有相同数据但结构不同的集合;例如,当我将条目从java.util.HashSet添加到java.util.LinkedHashSet时,后者将是前者的视图。这是对的吗?

有人可以通过指向 view 的已接受定义的链接与我联系,如果有的话吗?

感谢。

2 个答案:

答案 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(),它返回“指定列表的不可修改的视图”。换句话说,它返回一个列表,其中包含对委托所有操作的指定列表的引用。在这种情况下,返回的列表不允许您以任何方式修改它,因此,不是委托负责变更列表的方法,而是在调用此类方法时抛出异常。