【问题标题】:What is a view of a collection?什么是集合视图?
【发布时间】:2013-09-19 18:37:46
【问题描述】:

在使用Guava 集合并阅读其文档时,我已经阅读了几次view这个术语。

我一直在寻找关于在这种情况下视图是什么以及它是否是在 Guava 之外使用的术语的解释。它经常被使用here。这个来自 Guava 的 type 名称中有 view

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

如果有的话,谁能给我一个链接到公认的view定义?

谢谢。

【问题讨论】:

  • 不,我认为这不正确。如果您说LinkedHashSet lhs = new LinkedHashSet (hs) 其中hsHashSetlhs 将具有与hs 相同的元素引用,它将是它自己的数据结构。如果您从lhs 中删除一个元素,它不会影响hs,反之亦然。所以它们是不同的集合。但是如果你使用Collections.unmodifiableSet,那么你会得到一个引用同一个集合的视图。

标签: java collections guava


【解决方案1】:

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

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

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 允许您使用List API 访问普通数组; Map.keySet() 允许您访问 Map 的键,就好像它是一个完全普通的 Set - 所有无需复制数据或创建另一个数据结构。

一般来说,使用视图而不是复制的优点是效率。例如,如果您有一个数组并且您需要将它获取到一个采用List 的方法,那么您不会创建一个新的ArrayList 和数据的完整副本——Arrays.asList 视图只需要恒定的额外内存,并且只是通过访问原始数组来实现所有List 方法。

【讨论】:

  • 我明白了,谢谢。该术语是否有“官方”来源(例如设计模式和四人组)?
  • @mareser:我敢打赌它来自databases
  • @maaartinus 是“适配器”模式。有效的Java第三版,第20条提一下。
【解决方案2】:

在此上下文中的 视图 是由另一个集合(或数组)支持的集合,该集合本身使用恒定数量的内存(即内存不依赖于支持集合的大小)。应用于视图的操作被委托给支持集合(或数组)。当然,可以将此定义扩展到集合之外,但您的问题似乎专门针对它们。

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

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

【讨论】:

    猜你喜欢
    • 2011-03-22
    • 1970-01-01
    • 2023-04-02
    • 2011-12-27
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    相关资源
    最近更新 更多