集合视图是什么?


问题内容

在使用Guava集合并阅读其文档时,我已经阅读了几次“术语 视图”

我一直在寻找一种解释,说明在这种情况下视图是什么以及它是否在Guava之外使用。在这里经常使用。番石榴的这种类型在其名称中具有
视图

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

有人可以给我链接到一个公认的 view 定义(如果有)的链接吗?

谢谢。


问题答案:

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

例如,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),则无需进行任何其他操作即可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使您可以使用ListAPI访问普通数组;Map.keySet()使您可以Map像完全完美一样访问a的键Set-所有这些都
无需 复制数据或创建另一个数据结构。

通常,使用视图而不是进行复制的优点是效率。例如,如果您有一个数组,并且需要将其传递到采用的方法,则List您无需创建新ArrayList的数据副本和完整的数据副本-
Arrays.asList视图仅占用恒定的额外内存,并且仅实现所有List通过访问原始数组的方法。