Ответ 1
Вид другого объекта вообще не содержит собственных данных. Все его операции реализованы с точки зрения операций над другим объектом.
Например, представление 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
позволяет использовать API List
для доступа к нормальному массиву; Map.keySet()
позволяет вам получить доступ к клавишам Map
, как если бы это был совершенно обычный Set
- все без копирования данных или создания другой структуры данных.
Как правило, преимуществом использования представления вместо создания копии является эффективность. Например, если у вас есть массив, и вам нужно получить его для метода, который принимает List
, вы не создаете новый ArrayList
и целую копию данных - представление Arrays.asList
принимает только постоянной дополнительной памяти и просто реализует все методы List
, обращаясь к исходному массиву.