Ради полноты ...
Скажите , что вы действительно хотите , чтобы обработать Map
значения , как List
с, но вы хотите , чтобы избежать копирования Set
в List
каждый момент времени.
Например, может быть, вы вызываете одну библиотечную функцию, которая создает Set
, но вы передаете свой Map<String, List<String>>
результат библиотечной функции (плохо спроектированной, но не в ваших руках), которая только выполняет Map<String, List<String>>
, хотя каким- то образом вы знаете, что она выполняет операции с List
s одинаково применимы к любому Collection
(и, следовательно, к любому Set
). И по какой-то причине вам нужно избегать накладных расходов на скорость / память при копировании каждого набора в список.
В этом супер нишевом случае, в зависимости от (возможно, непознаваемого) поведения, необходимого библиотечной функции от вашего List
, вы можете создать List
представление для каждого набора. Обратите внимание, что это по сути небезопасно (поскольку требования библиотечной функции к каждой из них List
могут предположительно измениться без вашего ведома), поэтому следует предпочесть другое решение. Но вот как ты это сделаешь.
Вы создали бы класс, который реализует List
интерфейс, принимает Set
конструктор и присваивает это значение Set полю, а затем использует его Set
для реализации List
API (насколько это возможно и желательно).
Обратите внимание, что какое-то поведение List вы просто не сможете имитировать, не сохраняя элементы как a List
, а какое-то поведение вы сможете имитировать лишь частично. Опять же, этот класс не является безопасной заменой List
s в целом. В частности, если вы знаете, что сценарий использования требует операций, связанных с индексом, или MUTATING 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);
...