Per amor di completezza...
Supponiamo che tu voglia veramente trattare i Map
valori come List
s, ma vuoi evitare di copiarli Set
in List
ogni volta.
Ad esempio, forse stai chiamando una funzione di libreria che crea una Set
, ma stai passando il Map<String, List<String>>
risultato a una funzione di libreria (mal progettata ma fuori dalle tue mani) che richiede solo Map<String, List<String>>
, anche se in qualche modo sai che le operazioni che fa con List
sono ugualmente applicabili a qualsiasi Collection
(e quindi a qualsiasi Set
). E per qualche motivo è necessario evitare il sovraccarico di velocità / memoria della copia di ciascun set in un elenco.
In questo caso di super nicchia, a seconda del comportamento (forse inconoscibile) di cui la funzione di libreria necessita dai tuoi List
, potresti essere in grado di creare una List
vista su ogni set. Si noti che questo è intrinsecamente pericoloso (poiché i requisiti della funzione di libreria di ciascuno di essi List
potrebbero presumibilmente cambiare a tua insaputa), quindi un'altra soluzione dovrebbe essere preferita. Ma ecco come lo faresti.
Dovresti creare una classe che implementa l' List
interfaccia, prende un Set
nel costruttore e assegna quel Set a un campo, e poi usi quello interno Set
per implementare l' List
API (nella misura del possibile e desiderata).
Nota che alcuni comportamenti dell'elenco che semplicemente non sarai in grado di imitare senza memorizzare gli elementi come a List
, e alcuni comportamenti che potrai imitare solo parzialmente. Ancora una volta, questa classe non è un rimpiazzo sicuro per List
s in generale. In particolare, se sai che il caso d'uso richiede operazioni relative all'indice o MUTAZIONI List
, questo approccio andrebbe a sud molto velocemente.
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);
...