Você não pode, já Setque a não tem métodos de acesso aleatório (ou seja, .get()um elemento em um determinado índice), que é basicamente necessário para algoritmos de classificação;)
fge
3
Você poderia convertê-lo em uma lista primeiro e, em seguida, classificar se precisar classificar
demongolem
Você não pode, pois a HashSetnão tem uma ordem definida. Sua pergunta contém uma contradição de termos.
Apenas colocar os elementos não dará a flexibilidade de classificação em qualquer ordem com qualquer elemento dentro dela. A solução acima sim.
Jess
15
A maneira do Java 8 de classificar seria:
fooHashSet.stream().sorted(Comparator.comparing(Foo::getSize))//comparator - how you want to sort it.collect(Collectors.toList());//collector - what you want to collect it to
* Foo::getSizeé um exemplo de como classificar o HashSet de YourItem naturalmente por tamanho.
* Collectors.toList()vai coletar o resultado da classificação em uma lista que você precisará capturar comList<Foo> sortedListOfFoo =
Por que você está presumindo que eles armazenam Stringvalores?
Sotirios Delimanolis
Não estou, talvez meu uso de lexográfico seja impreciso ;-)
P45 Iminente
3
É muito errado. Ele não armazena chaves em ordem lexográfica (sp?). Ele usa sua ordem natural (que depende da Comparableinterface que as chaves implementam) ou usa a fornecida Comparator.
Sotirios Delimanolis
Eu editei. Melhor você acha, ou devo deletar a resposta?
P45 iminente
1
Caso você mova um HashSetpara TreeSet, sua classe deve implementar uma Comparableinterface ou fornecer um personalizado Comparator. Caso contrário, como você não pode classificar um HashSet, apenas converta-o em a Liste classifique-o.
Os elementos no HashSet não podem ser classificados. Sempre que você coloca elementos no HashSet, pode bagunçar a ordem de todo o conjunto. É deliberadamente projetado assim para desempenho. Quando você não se importa com o pedido, o HashSet será o conjunto mais eficiente para inserção e pesquisa rápidas.
TreeSet classificará todos os elementos automaticamente sempre que você inserir um elemento.
Talvez o que você esteja tentando fazer seja classificar apenas uma vez. Nesse caso, TreeSet não é a melhor opção porque precisa determinar a colocação de elementos recém-adicionados o tempo todo.
A solução mais eficiente é usar ArrayList. Crie uma nova lista e adicione todos os elementos e, em seguida, classifique-a uma vez. Se você quiser reter apenas elementos únicos (remova todas as duplicatas como o conjunto faz e, em seguida, coloque a lista em um LinkedHashSet, ele manterá a ordem que você já classificou)
List<Integer> list =newArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);Collections.sort(list);Set<Integer> unique =newLinkedHashSet<>(list);// 4 5 6// The above line is not copying the objects! It only copies references.
Agora, você obteve um conjunto classificado se quiser em uma forma de lista e então converta-o em lista.
Na minha humilde opinião, a resposta de LazerBanana deve ser a resposta mais bem avaliada e aceita porque todas as outras respostas que apontam para java.util.TreeSet(ou primeiro converta para lista e depois chame Collections.sort(...)a lista convertida) não se preocuparam em perguntar a OP como que tipo de objetos você HashSettem. se esses elementos têm uma ordem natural predefinida ou não e essa não é uma questão opcional, mas uma questão obrigatória.
Você simplesmente não pode entrar e começar a colocar seus HashSetelementos em um TreeSettipo de elemento if ainda não implementa a Comparableinterface ou se você não estiver passando explicitamente Comparatorpara o TreeSetconstrutor.
Do TreeSetJavaDoc,
Constrói um novo conjunto de árvore vazio, classificado de acordo com a ordem natural de seus elementos. Todos os elementos inseridos no conjunto devem implementar a interface Comparable. Além disso, todos esses elementos devem ser mutuamente comparáveis: e1.compareTo (e2) não deve lançar uma ClassCastException para quaisquer elementos e1 e e2 no conjunto. Se o usuário tentar adicionar um elemento ao conjunto que viole essa restrição (por exemplo, o usuário tenta adicionar um elemento de string a um conjunto cujos elementos são inteiros), a chamada add lançará uma ClassCastException.
É por isso que apenas todas as respostas baseadas em fluxo Java8 - onde você define seu comparador no local - só fazem sentido porque implementar comparável em POJO se torna opcional. O programador define o comparador como e quando necessário. Tentar coletar TreeSetsem fazer essa pergunta fundamental também é incorreto (resposta de Ninja). Supondo que os tipos de objeto sejam Stringou Integertambém estejam incorretos.
Dito isso, outras preocupações como,
Desempenho de classificação
Memory Foot Print (mantendo o conjunto original e criando novos conjuntos classificados cada vez que a classificação é feita ou deseja classificar o conjunto no local etc etc)
devem ser os outros pontos relevantes também. Apenas apontar para a API não deve ser apenas uma intenção.
Como o conjunto original já contém apenas elementos únicos e essa restrição também é mantida pelo conjunto classificado, o conjunto original precisa ser apagado da memória, uma vez que os dados são duplicados.
1.Add all set element in list -> al.addAll(s);2.Sort all the elements in list using ->Collections.sort(al);publicclassSortSetProblem{publicstaticvoid main(String[] args){ArrayList<String> al =newArrayList();Set<String> s =newHashSet<>();
s.add("ved");
s.add("prakash");
s.add("sharma");
s.add("apple");
s.add("ved");
s.add("banana");System.out.println("Before Sorting");for(String s1 : s){System.out.print(" "+ s1);}System.out.println("After Sorting");
al.addAll(s);Collections.sort(al);for(String set : al){System.out.print(" "+ set);}}}
Se você deseja que o final Collectiontenha a forma de Sete se deseja definir o seu próprio natural orderem vez de TreeSetentão -
1. Converta o HashSetem List
2. Classifique o personalizado Listusando Comparator
3. Converta de volta o Listem LinkedHashSetpara manter a ordem
4. Exiba o LinkedHashSet
Não podemos decidir se os elementos de um HashSet seriam classificados automaticamente. Mas podemos classificá-los convertendo em TreeSet ou qualquer lista como ArrayList ou LinkedList etc.
// Create a TreeSet object of class ETreeSet<E> ts =newTreeSet<E>();// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);System.out.println(ts.toString()+"\t Sorted Automatically");
Eu usei isso dentro de uma instrução de impressão, então se você realmente precisa persistir a ordem, você pode precisar usar TreeSets ou outras estruturas propostas neste thread.
HashSet
é uma coleção não ordenada.Set
que a não tem métodos de acesso aleatório (ou seja,.get()
um elemento em um determinado índice), que é basicamente necessário para algoritmos de classificação;)HashSet
não tem uma ordem definida. Sua pergunta contém uma contradição de termos.Respostas:
Um HashSet não garante nenhuma ordem de seus elementos. Se você precisar dessa garantia, considere usar um TreeSet para manter seus elementos.
No entanto, se você só precisa que seus elementos sejam classificados para esta ocorrência, crie temporariamente uma Lista e classifique-a:
fonte
List<String> sortedList = new ArrayList<String>(yourHashSet);
Adicione todos os seus objetos ao
TreeSet
, você obterá um Conjunto ordenado. Abaixo está um exemplo bruto.fonte
TreeSet myTreeSet = new TreeSet(myHashSet);
você pode evitar adicionar todos os elementos ao Treeset novamente.Você pode usar um TreeSet .
fonte
A maneira do Java 8 de classificar seria:
*
Foo::getSize
é um exemplo de como classificar o HashSet de YourItem naturalmente por tamanho.*
Collectors.toList()
vai coletar o resultado da classificação em uma lista que você precisará capturar comList<Foo> sortedListOfFoo =
fonte
Use
java.util.TreeSet
como o objeto real. Quando você itera nessa coleção, os valores voltam em uma ordem bem definida.Se você usar
java.util.HashSet
, a ordem depende de uma função hash interna que quase certamente não é lexicográfica (com base no conteúdo).fonte
String
valores?Comparable
interface que as chaves implementam) ou usa a fornecidaComparator
.HashSet
paraTreeSet
, sua classe deve implementar umaComparable
interface ou fornecer um personalizadoComparator
. Caso contrário, como você não pode classificar umHashSet
, apenas converta-o em aList
e classifique-o.Você pode usar coletores Java 8 e TreeSet
list.stream().collect(Collectors.toCollection(TreeSet::new))
fonte
new TreeSet<>(hashSet)
é mais conciso e provavelmente mais eficiente.Você pode usar TreeSet conforme mencionado em outras respostas.
Aqui está um pouco mais de elaboração sobre como usá-lo:
Resultado:
fonte
Os elementos no HashSet não podem ser classificados. Sempre que você coloca elementos no HashSet, pode bagunçar a ordem de todo o conjunto. É deliberadamente projetado assim para desempenho. Quando você não se importa com o pedido, o HashSet será o conjunto mais eficiente para inserção e pesquisa rápidas.
TreeSet classificará todos os elementos automaticamente sempre que você inserir um elemento.
Talvez o que você esteja tentando fazer seja classificar apenas uma vez. Nesse caso, TreeSet não é a melhor opção porque precisa determinar a colocação de elementos recém-adicionados o tempo todo.
A solução mais eficiente é usar ArrayList. Crie uma nova lista e adicione todos os elementos e, em seguida, classifique-a uma vez. Se você quiser reter apenas elementos únicos (remova todas as duplicatas como o conjunto faz e, em seguida, coloque a lista em um LinkedHashSet, ele manterá a ordem que você já classificou)
Agora, você obteve um conjunto classificado se quiser em uma forma de lista e então converta-o em lista.
fonte
Com base na resposta dada por @LazerBanana, irei colocar meu próprio exemplo de um Conjunto classificado pelo Id do Objeto:
fonte
Apenas no caso de você não querer usar um,
TreeSet
você pode tentar isso.fonte
Na minha humilde opinião, a resposta de LazerBanana deve ser a resposta mais bem avaliada e aceita porque todas as outras respostas que apontam para
java.util.TreeSet
(ou primeiro converta para lista e depois chameCollections.sort(...)
a lista convertida) não se preocuparam em perguntar a OP como que tipo de objetos vocêHashSet
tem. se esses elementos têm uma ordem natural predefinida ou não e essa não é uma questão opcional, mas uma questão obrigatória.Você simplesmente não pode entrar e começar a colocar seus
HashSet
elementos em umTreeSet
tipo de elemento if ainda não implementa aComparable
interface ou se você não estiver passando explicitamenteComparator
para oTreeSet
construtor.Do
TreeSet
JavaDoc,É por isso que apenas todas as respostas baseadas em fluxo Java8 - onde você define seu comparador no local - só fazem sentido porque implementar comparável em POJO se torna opcional. O programador define o comparador como e quando necessário. Tentar coletar
TreeSet
sem fazer essa pergunta fundamental também é incorreto (resposta de Ninja). Supondo que os tipos de objeto sejamString
ouInteger
também estejam incorretos.Dito isso, outras preocupações como,
devem ser os outros pontos relevantes também. Apenas apontar para a API não deve ser apenas uma intenção.
Como o conjunto original já contém apenas elementos únicos e essa restrição também é mantida pelo conjunto classificado, o conjunto original precisa ser apagado da memória, uma vez que os dados são duplicados.
fonte
fonte
Se você deseja que o final
Collection
tenha a forma deSet
e se deseja definir o seu próprionatural order
em vez deTreeSet
então -1. Converta o
HashSet
emList
2. Classifique o personalizado
List
usandoComparator
3. Converta de volta o
List
emLinkedHashSet
para manter a ordem4. Exiba o
LinkedHashSet
Programa de amostra -
Resultado -
Aqui, a coleção foi classificada como -
Primeira - Ordem decrescente de
String
comprimentoSegundo - Ordem decrescente da
String
hierarquia alfabéticafonte
você pode fazer isso das seguintes maneiras:
Método 1:
Método 2:
O método 2 é mais preferível porque o outro método consome muito tempo para transferir dados entre o conjunto de hash e a lista.
fonte
Não podemos decidir se os elementos de um HashSet seriam classificados automaticamente. Mas podemos classificá-los convertendo em TreeSet ou qualquer lista como ArrayList ou LinkedList etc.
fonte
Você pode usar a biblioteca de goiaba para o mesmo
fonte
SortedSet foi adicionado desde java 7 https://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html
fonte
Você pode envolvê-lo em um TreeSet como este:
saída:
itens mySet [1, 3, 4, 5]
itens treeSet [1, 3, 4, 5]
saída:
itens mySet [seis, quatro, cinco, dois, elfo]
treeSet itens [elfo, cinco, quatro, seis, dois]
O requisito para este método é que os objetos do conjunto / lista sejam comparáveis (implemente a interface Comparável)
fonte
Este comando simples funcionou para mim:
Eu usei isso dentro de uma instrução de impressão, então se você realmente precisa persistir a ordem, você pode precisar usar TreeSets ou outras estruturas propostas neste thread.
fonte
toList
.