什么是集合的视图?

Mat*_*aun 12 java collections guava

在使用Guava集合并阅读其文档时,我一直在阅读术语视图几次.

我已经在这个背景下寻找一个视图的解释,以及它是否是在番石榴之外使用的术语.它经常在这里使用.Guava的这种类型有其名称的视图.

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

有人可以用一个链接来接受一个已接受的视图定义,如果有的话吗?

谢谢.

Lou*_*man 20

另一个对象的视图根本不包含自己的数据.它的所有操作都是根据对另一个对象的操作实现的.

例如,a的keySet()视图Map可能具有如下所示的实现:

class KeySet implements Set<K> {
  private final Map<K, V> map;

  public boolean contains(Object o) {
    return map.containsKey(o);
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

特别是,当你修改支持对象视图的-在这里,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"
Run Code Online (Sandbox Code Playgroud)

视图只是查看原始支持对象中数据的另一种方式 - Arrays.asList允许您使用ListAPI访问普通数组; Map.keySet()允许您访问a的键,Map就好像它是完全普通的Set- 所有这些都不会复制数据或创建其他数据结构.

通常,使用视图而不是制作副本的优点是效率.例如,如果你有一个数组,你需要将它带到一个带有a的方法List,你不是创建一个新的ArrayList和整个数据副本 - Arrays.asList视图只需要不断的额外内存,并且只实现所有的List通过访问原始数组的方法.


ars*_*jii 6

视图在该上下文中是指用另一个集合(或阵列)支持的集合,该集合本身使用恒定量存储器(即存储器不依赖于所述背衬集合的大小).应用于视图的操作将委派给后备集合(或数组).当然,有可能将此定义扩展到仅仅集合之外,但您的问题似乎与它们有关.

例如,Arrays.asList()返回"指定数组的列表视图".它不会将元素复制到新列表,而是创建一个包含对数组的引用的列表,并根据该列表进行操作.

另一个例子是Collections.unmodifiableList()返回"指定列表的不可修改的视图".换句话说,它返回一个列表,其中包含对委托所有操作的指定列表的引用.在这种情况下,返回的列表不允许您以任何方式修改它,因此,而不是委托负责变更列表的方法,而是在调用此类方法时抛出异常.