Próbuję znaleźć implementację java.util.List
i java.util.Set
jednocześnie w Javie. Chcę, aby ta klasa zezwalała tylko na unikalne elementy (as Set
) i zachowywała ich kolejność (jak List
). Czy istnieje w JDK 6?
Jest to ważne, aby List<T>#add(int, T)
móc wstawić w określonej pozycji.
java
collections
yegor256
źródło
źródło
Comparator
? Czy chcesz również poznać semantykęList
interfejsu?Odpowiedzi:
TreeSet
jest sortowany według kolejności elementów;LinkedHashSet
zachowuje zamówienie reklamowe. Mam nadzieję, że jednym z nich jest to, czego szukałeś.Określiłeś, że chcesz mieć możliwość wstawiania w dowolnym miejscu, podejrzewam, że będziesz musiał napisać własną - po prostu utwórz klasę zawierającą a
HashSet<T>
iArrayList<T>
; dodając element, sprawdź, czy znajduje się w zestawie przed dodaniem go do listy.Alternatywnie, oferowane przez Apache wspólne kolekcje4
ListOrderedSet
iSetUniqueList
, które zachowują się podobnie i powinny spełniać podane wymagania.źródło
Odpowiedzią jest LinkedHashSet.
Kolejność iteracji i niepowtarzalność.
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
źródło
List
interfejsu, zobacz moje zmiany w pytaniuCzy masz na myśli jak
LinkedHashSet
? To zachowuje kolejność wpisów, ale nie zezwala na duplikaty.IMHO, to niezwykłe wymaganie, ale możesz napisać listę bez duplikatów.
class SetList<T> extends ArrayList<T> { @Override public boolean add(T t) { return !super.contains(t) && super.add(t); } @Override public void add(int index, T element) { if (!super.contains(element)) super.add(index, element); } @Override public boolean addAll(Collection<? extends T> c) { boolean added = false; for (T t : c) added |= add(t); return added; } @Override public boolean addAll(int index, Collection<? extends T> c) { boolean added = false; for (T t : c) if (!super.contains(t)) { super.add(index++, t); added = true; } return added; } }
źródło
List
interfejsu, zobacz moje zmiany w pytaniuO(n)
złożoności wstawiania, istnieje kompromis, który należy rozważyć między podwójnym przechowywaniem aO(log(n))
operacją wstawiania.Nie możesz wdrożyć
List
iSet
od razu bez naruszenia umowy. Zobacz na przykładSet.hashCode
umowę:Z drugiej strony oto umowa
List.hashCode
:Nie można więc zaimplementować jednej klasy, która gwarantuje wykonanie obu umów. Ten sam problem do
equals
realizacji.źródło
Jeśli nie ograniczysz się do JDK 6, możesz skorzystać z biblioteki wspólnych kolekcji Apache, która oferuje dokładne dopasowanie do Twoich potrzeb - ListOrderedSet . To jest jak
List
iSet
połączone razem :)źródło
List
interfejsuMiałem podobny problem, więc napisałem własny. Zobacz tutaj .
IndexedArraySet
RozciągaArrayList
i narzędziaSet
, dlatego należy wspierać wszelkie działania, które są potrzebne. Zwróć uwagę, że wstawianie elementów do lokalizacji w środkuArrayList
może być powolne w przypadku dużych list, ponieważ wszystkie kolejne elementy muszą zostać przeniesione. MójIndexedArraySet
nie zmienia tego.źródło
Inną opcją (bez
List
wymogu interfejsu) jest GuavaImmutableSet
, która zachowuje kolejność reklam. Z ich strony wiki :źródło