Заради повноти ...
Скажіть , що ви дійсно хочете , щоб обробити Map
значення , як List
з, але ви хочете , щоб уникнути копіювання Set
в List
кожен момент часу.
Наприклад, можливо, ви викликаєте одну функцію бібліотеки, яка створює Set
, але ви передаєте свій Map<String, List<String>>
результат (погано розроблена, але не з ваших рук) функція бібліотеки, яка займає лише те Map<String, List<String>>
, хоча якимось чином ви знаєте, що операції виконуються з List
s однаково застосовні для будь-якого Collection
(і, отже, будь-якого Set
). І чомусь вам потрібно уникати швидкості / накладних витрат на копіювання кожного набору в список.
У цьому випадку супер ніші, залежно від поведінки (можливо непізнаваної), яку потребує функція бібліотеки у ваших List
системах, ви зможете створити List
представлення для кожного набору. Зауважте, що це по суті небезпечно (оскільки вимоги до функцій бібліотеки від кожного List
можуть, мабуть, змінитися, не знаючи), тому слід віддавати перевагу іншому рішенню. Але ось як би ви це зробили.
Ви б створили клас, який реалізує List
інтерфейс, приймає Set
конструктор і призначає поле "Встановити", а потім використовує цей внутрішній Set
для реалізації List
API (наскільки це можливо та бажано).
Зауважте, що деяка поведінка списку, яку ви просто не зможете наслідувати, не зберігаючи елементи як а List
, а деяку поведінку ви лише частково зможете наслідувати. Знову ж таки, цей клас взагалі не є безпечною заміною для List
s. Зокрема, якщо ви знаєте, що для використання випадку потрібні операції, пов’язані з індексом, або ВИМКНЕННЯ List
, цей підхід піде на південь дуже швидко.
public class ListViewOfSet<U> implements List<U> {
private final Set<U> wrappedSet;
public ListViewOfSet(Set<U> setToWrap) { this.wrappedSet = setToWrap; }
@Override public int size() { return this.wrappedSet.size(); }
@Override public boolean isEmpty() { return this.wrappedSet.isEmpty(); }
@Override public boolean contains(Object o) { return this.wrappedSet.contains(o); }
@Override public java.util.Iterator<U> iterator() { return this.wrappedSet.iterator(); }
@Override public Object[] toArray() { return this.wrappedSet.toArray(); }
@Override public <T> T[] toArray(T[] ts) { return this.wrappedSet.toArray(ts); }
@Override public boolean add(U e) { return this.wrappedSet.add(e); }
@Override public boolean remove(Object o) { return this.wrappedSet.remove(o); }
@Override public boolean containsAll(Collection<?> clctn) { return this.wrappedSet.containsAll(clctn); }
@Override public boolean addAll(Collection<? extends U> clctn) { return this.wrappedSet.addAll(clctn); }
@Override public boolean addAll(int i, Collection<? extends U> clctn) { throw new UnsupportedOperationException(); }
@Override public boolean removeAll(Collection<?> clctn) { return this.wrappedSet.removeAll(clctn); }
@Override public boolean retainAll(Collection<?> clctn) { return this.wrappedSet.retainAll(clctn); }
@Override public void clear() { this.wrappedSet.clear(); }
@Override public U get(int i) { throw new UnsupportedOperationException(); }
@Override public U set(int i, U e) { throw new UnsupportedOperationException(); }
@Override public void add(int i, U e) { throw new UnsupportedOperationException(); }
@Override public U remove(int i) { throw new UnsupportedOperationException(); }
@Override public int indexOf(Object o) { throw new UnsupportedOperationException(); }
@Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); }
@Override public ListIterator<U> listIterator() { throw new UnsupportedOperationException(); }
@Override public ListIterator<U> listIterator(int i) { throw new UnsupportedOperationException(); }
@Override public List<U> subList(int i, int i1) { throw new UnsupportedOperationException(); }
}
...
Set<String> set = getSet(...);
ListViewOfSet<String> listOfNames = new ListViewOfSet<>(set);
...