19

I've been reading the term view a few times when using Guava collections and reading its documentation.

I've looked for an explanation of what a view is in this context and whether it's a term used outside of Guava. It's quite often used here. This type from Guava has view in its name.

My guess is that a view of a collection is another collection with the same data but structured differently; for instance when I add the entries from a java.util.HashSet to a java.util.LinkedHashSet the latter would be a view of the former. Is that correct?

Can somebody hook me up with a link to an accepted definition of view, if there is one?

Thanks.

sebkur
  • 658
  • 2
  • 9
  • 18
Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
  • 1
    No, I don't think this is correct. If you say `LinkedHashSet lhs = new LinkedHashSet (hs)` where `hs` is a `HashSet`, `lhs` will have the same element references as `hs`, *but* it will be its own data structure. If you remove an element from `lhs`, it will **not** affect `hs`, and vice versa. So they're distinct collections. But if you use `Collections.unmodifiableSet`, then you do get a view that refers to the same collection. – ajb Sep 19 '13 at 18:48

2 Answers2

26

A view of another object doesn't contain its own data at all. All of its operations are implemented in terms of operations on the other object.

For example, the keySet() view of a Map might have an implementation that looks something like this:

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

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

  ...
}

In particular, whenever you modify the backing object of your view -- here, the Map backs the keySet() -- the view reflects the same changes. For example, if you call map.remove(key), then keySet.contains(key) will return false without you having to do anything else.

Alternately, Arrays.asList(array) provides a List view of that array.

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"

A view is just another way of looking at the data in the original backing object -- Arrays.asList lets you use the List API to access a normal array; Map.keySet() lets you access the keys of a Map as if it were a perfectly ordinary Set -- all without copying the data or creating another data structure.

Generally, the advantage of using a view instead of making a copy is the efficiency. For example, if you have an array and you need to get it to a method that takes a List, you're not creating a new ArrayList and a whole copy of the data -- the Arrays.asList view takes only constant extra memory, and just implements all the List methods by accessing the original array.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • 1
    I understand, thanks. Is there an 'official' source of that term (like with Design Patterns and the Gang of Four)? – Matthias Braun Sep 19 '13 at 19:19
  • 1
    @mareser: I'd bet it comes from [databases](http://en.wikipedia.org/wiki/View_(SQL)). – maaartinus Sep 25 '13 at 16:51
  • @maaartinus It is "Adapter" pattern.Effective Java Third Edition,Item 20 mention it. – LiLi Jun 06 '20 at 08:28
  • I am still confused, the view is simply a copy of a Structure, which has no link to original data, but I can use that to get details of actual dat using it ? Your Keyset example is unclear to me. – RAHUL JAISWAL Jul 23 '22 at 13:53
  • "the view is simply a copy of a Structure, which has no link to original data" No. This is wrong. Nothing is copied, there is just a link to the original data. – Louis Wasserman Jul 23 '22 at 14:57
9

A view in this context is a collection backed by another collection (or array) that itself uses a constant amount memory (i.e. the memory does not depend on the size of the backing collection). Operations applied to the view are delegated to the backing collection (or array). Of course it's possible to expand this definition beyond just collections but your question seems to pertain specifically to them.

For example, Arrays.asList() returns "a list view of the specified array". It does not copy the elements to a new list but rather creates a list that contains a reference to the array and operates based on that.

Another example is Collections.unmodifiableList() which returns "an unmodifiable view of the specified list". In other words, it returns a list containing a reference to the specified list to which all operations are delegated. In this case, the list returned does not permit you to modify it in any way, and so instead of delegating methods responsible for mutating the list, it throws an exception when such methods are called instead.

arshajii
  • 127,459
  • 24
  • 238
  • 287