Estou tentando encontrar uma implementação de java.util.List
e java.util.Set
ao mesmo tempo em Java. Quero que essa classe permita apenas elementos exclusivos (as Set
) e preserve sua ordem (como List
). Ele existe no JDK 6?
É importante ter List<T>#add(int, T)
para que eu possa inserir em uma posição específica.
java
collections
Yegor256
fonte
fonte
Comparator
? Você também quer a semântica daList
interface?Respostas:
TreeSet
é classificado por ordem de elemento;LinkedHashSet
retém o pedido de inserção. Esperançosamente, um desses é o que você estava procurando.Você especificou que deseja inserir em um local arbitrário , suspeito que você terá que escrever o seu próprio - basta criar uma classe contendo um
HashSet<T>
e umArrayList<T>
; ao adicionar um item, verifique se ele está ou não no conjunto antes de adicioná-lo à lista.Como alternativa, as ofertas commons-Collections4 do Apache
ListOrderedSet
eSetUniqueList
, que se comportam de maneira semelhante e devem atender aos requisitos fornecidos.fonte
LinkedHashSet é a resposta.
Ordem de iteração e exclusividade.
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
fonte
List
interface, veja minhas alterações na perguntaVocê quer dizer gostar
LinkedHashSet
? Isso preserva a ordem de entrada, mas não permite duplicatas.IMHO, é um requisito incomum, mas você pode escrever uma lista sem duplicatas.
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; } }
fonte
List
interface, veja minhas alterações na perguntaO(n)
complexidade de inserção, há uma troca que deve ser considerada entre armazenamento duplo eO(log(n))
operação de inserção.Você não pode implementar
List
e deSet
uma vez sem violação do contrato. Veja, por exemplo, oSet.hashCode
contrato:Por outro lado, aqui está o contrato de
List.hashCode
:Portanto, é impossível implementar aula única que garanta o cumprimento de ambos os contratos. O mesmo problema para
equals
implementação.fonte
Se você não se limitar ao JDK 6, poderá usar a biblioteca de coleções comuns do Apache, que oferece a correspondência exata para sua necessidade - ListOrderedSet . É como
List
eSet
combinado :)fonte
List
interfaceEu tive um problema semelhante, então escrevi o meu próprio. Veja aqui . O
IndexedArraySet
estendeArrayList
e implementaSet
, portanto, deve oferecer suporte a todas as operações de que você precisa. Observe que inserir elementos em locais no meio de umaArrayList
pode ser lento para listas grandes porque todos os elementos a seguir precisam ser movidos. MeuIndexedArraySet
não muda isso.fonte
Outra opção (sem o
List
requisito de interface) é o Guava'sImmutableSet
, que preserva a ordem de inserção. De sua página wiki :fonte