Em Java, há o SortedSet
eSortedMap
interfaces . Ambos pertencem à estrutura Java Collections e fornecem uma maneira classificada de acessar os elementos.
No entanto, no meu entendimento, não há SortedList
em Java. Você pode usarjava.util.Collections.sort()
para classificar uma lista.
Alguma idéia de por que é projetado assim?
java
sorting
collections
Jijoy
fonte
fonte
int diff = this.score - that.score;
return (diff == 0) ? 1 : diff;
como é um hack fedorento, eu o forneceria como um argumento construtor anônimo, em vez de ter qualquer implementação comparável.Respostas:
Os iteradores da lista garantem, em primeiro lugar, que você obtenha os elementos da lista na ordem interna da lista (também conhecida como ordem de inserção ). Mais especificamente, está na ordem em que você inseriu os elementos ou em como você manipulou a lista. A classificação pode ser vista como uma manipulação da estrutura de dados e há várias maneiras de classificar a lista.
Vou ordenar os caminhos na ordem de utilidade que eu pessoalmente vejo:
1. Considere usar
Set
ouBag
coleçõesNOTA: Coloquei essa opção no topo, porque é isso que você normalmente deseja fazer.
Um conjunto classificado classifica automaticamente a coleção na inserção , o que significa que faz a classificação enquanto você adiciona elementos à coleção. Isso também significa que você não precisa classificá-lo manualmente.
Além disso, se você tiver certeza de que não precisa se preocupar (ou ter) elementos duplicados, poderá usá-lo
TreeSet<T>
. Ele implementaSortedSet
eNavigableSet
interfaces e obras como você provavelmente esperaria de uma lista:Se você não deseja a ordem natural, pode usar o parâmetro construtor que recebe a
Comparator<T>
.Como alternativa, você pode usar Multisets (também conhecidos como Bags ) , ou seja,
Set
que permite elementos duplicados, e existem implementações de terceiros. Mais notavelmente das bibliotecas do Guava, existe umTreeMultiset
, que funciona muito como oTreeSet
.2. Classifique sua lista com
Collections.sort()
Como mencionado acima, a classificação de
List
s é uma manipulação da estrutura de dados. Portanto, para situações em que você precisa de "uma fonte de verdade" que será classificada de várias maneiras, classificá-la manualmente é o caminho a percorrer.Você pode classificar sua lista com o
java.util.Collections.sort()
método Aqui está um exemplo de código sobre como:Usando comparadores
Um benefício claro é que você pode usar
Comparator
nosort
método. Java também fornece algumas implementações paraComparator
asCollator
que são úteis para seqüências de classificação sensíveis ao código do idioma. Aqui está um exemplo:Classificação em ambientes simultâneos
Observe, porém, que o uso do
sort
método não é amigável em ambientes simultâneos, pois a instância da coleção será manipulada e, em vez disso, você deve considerar o uso de coleções imutáveis. Isso é algo que o Guava fornece naOrdering
classe e é uma linha simples:3. Envolva sua lista com
java.util.PriorityQueue
Embora não exista uma lista classificada em Java, existe uma fila classificada que provavelmente funcionaria bem para você. É a
java.util.PriorityQueue
classe.Nico Haase vinculou nos comentários a uma pergunta relacionada que também responde a isso.
Em uma coleção classificada, você provavelmente não deseja manipular a estrutura de dados interna, e é por isso que o PriorityQueue não implementa a interface List (porque isso lhe daria acesso direto a seus elementos).
Advertência sobre o
PriorityQueue
iteradorA
PriorityQueue
classe implementa as interfacesIterable<E>
eCollection<E>
para que possa ser iterada como de costume. No entanto, não é garantido que o iterador retorne elementos na ordem classificada. Em vez disso (como Alderath aponta nos comentários), você precisa ficarpoll()
na fila até ficar vazio.Observe que você pode converter uma lista em uma fila de prioridade por meio do construtor que utiliza qualquer coleção :
4. Escreva sua própria
SortedList
turmaNOTA: Você não precisa fazer isso.
Você pode escrever sua própria classe List, que é classificada sempre que adicionar um novo elemento. Isso pode tornar a computação pesada, dependendo da sua implementação e não faz sentido , a menos que você queira fazer isso como um exercício, por dois motivos principais:
List<E>
interface possui, porque osadd
métodos devem garantir que o elemento resida no índice especificado pelo usuário.No entanto, se você quiser fazer isso como um exercício, aqui está um exemplo de código para começar, ele usa a
AbstractList
classe abstract:Observe que se você não substituiu os métodos necessários, as implementações padrão de
AbstractList
irão lançarUnsupportedOperationException
s.fonte
Integer maxVal = prioQueue.peek(prioQueue.size() - 1);
. Em segundo lugar, se você pretende usar o PriorityQueue simplesmente como uma lista classificada, parecerá menos intuitivo verPriorityQueue
o código do que teria sidoSortedList
, se essa estrutura de dados existisse.Collections.sort()
ainda permite definir a função de comparação usada para classificar, usando umComparator
objeto.Como o conceito de uma lista é incompatível com o conceito de uma coleção classificada automaticamente. O objetivo de uma lista é que, após a chamada
list.add(7, elem)
, uma chamada paralist.get(7)
retornaráelem
. Com uma lista classificada automaticamente, o elemento pode terminar em uma posição arbitrária.fonte
Como todas as listas já estão "classificadas" pela ordem em que os itens foram adicionados (ordem FIFO), você pode "recorrer" a elas com outra ordem, incluindo a ordem natural dos elementos, usando
java.util.Collections.sort()
.EDITAR:
As listas como estruturas de dados são baseadas no que é interessante é a ordem na qual os itens foram inseridos.
Os conjuntos não possuem essa informação.
Se você deseja pedir adicionando tempo, use
List
. Se você deseja solicitar por outros critérios, useSortedSet
.fonte
Set e Map são estruturas de dados não lineares. Lista é estrutura de dados linear.
A estrutura de dados
SortedSet
e asSortedMap
interfaces da árvore implementamTreeSet
e,TreeMap
respectivamente, usando o algoritmo de implementação de árvore Red-Black usado . Portanto, verifique se não há itens duplicados (ou chaves no caso deMap
).List
já mantém uma coleção ordenada e uma estrutura de dados baseada em índice, as árvores não são estruturas de dados baseadas em índice.Tree
por definição, não pode conter duplicatas.List
podemos ter duplicatas, então não háTreeList
(ou seja, nãoSortedList
).java.util.Collections.sort()
. Ele classifica a lista especificada em ordem crescente, de acordo com a ordem natural de seus elementos.fonte
JavaFX
SortedList
Embora tenha demorado um pouco, o Java 8 tem uma classificação
List
. http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.htmlComo você pode ver nos javadocs, ele faz parte das coleções JavaFX , destinadas a fornecer uma exibição classificada em um ObservableList.
Atualização: Observe que, com o Java 11, o kit de ferramentas JavaFX foi movido para fora do JDK e agora é uma biblioteca separada. O JavaFX 11 está disponível como um SDK para download ou no MavenCentral. Consulte https://openjfx.io
fonte
Para todos os recém-chegados, a partir de abril de 2015, o Android agora possui uma classe SortedList na biblioteca de suporte, projetada especificamente para trabalhar
RecyclerView
. Aqui está o post sobre isso.fonte
Outro ponto é a complexidade do tempo das operações de inserção. Para uma inserção de lista, espera-se uma complexidade de O (1). Mas isso não pode ser garantido com uma lista classificada.
E o ponto mais importante é que as listas não assumem nada sobre seus elementos. Por exemplo, você pode fazer listas de coisas que não implementam
equals
oucompare
.fonte
SortedSet
coisas que não implementamComparable
. Veja este construtor TreeSet .List
interface Java não garante nenhuma especificação de desempenho em seus métodos.Pense nisso como este: a
List
interface possui métodos comoadd(int index, E element)
,set(int index, E element)
. O contrato é que, depois de adicionar um elemento na posição X, você o encontrará, a menos que adicione ou remova elementos antes dele.Se alguma implementação de lista armazenasse elementos em alguma ordem que não fosse o índice, os métodos de lista acima não teriam sentido.
fonte
A primeira linha da API da lista diz que é uma coleção ordenada (também conhecida como sequência). Se você classificar a lista, não poderá manter a ordem, portanto, não haverá TreeList em Java.
Como a API diz, a lista Java foi inspirada na sequência e veja as propriedades da sequência http://en.wikipedia.org/wiki/Sequence_(mathematics )
Isso não significa que você não pode classificar a lista, mas o Java é estrito à sua definição e não fornece versões classificadas das listas por padrão.
fonte
Caso você esteja procurando uma maneira de classificar elementos, mas também possa acessá-los por índice de maneira eficiente, faça o seguinte:
ArrayList
)Em seguida, para adicionar ou remover um elemento, você pode usar
Collections.binarySearch
para obter o índice de inserção / remoção. Como sua lista implementa o acesso aleatório, você pode modificar eficientemente a lista com o índice determinado.Exemplo:
fonte
Considere usar o mapa da árvore indexada . É um TreeSet aprimorado do JDK que fornece acesso ao elemento por índice e localiza o índice de um elemento sem iteração ou listas subjacentes ocultas que fazem backup da árvore. O algoritmo é baseado na atualização de pesos dos nós alterados toda vez que há uma alteração.
fonte