如何对HashSet进行排序?

时间:2014-03-13 21:29:43

标签: java sorting collections set hashset

对于列表,我们使用Collections.sort(List)方法。如果我们要对HashSet进行排序怎么办?

19 个答案:

答案 0 :(得分:92)

HashSet不保证其元素的任何顺序。如果您需要此保证,请考虑使用TreeSet来保存元素。

但是,如果你只需要为这一次出现排序的元素,那么只需临时创建一个List并对其进行排序:

Set<?> yourHashSet = new HashSet<>();

...

List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);

答案 1 :(得分:55)

将所有对象添加到TreeSet,您将获得一个已排序的Set。以下是一个原始示例。

HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]

答案 2 :(得分:13)

使用java.util.TreeSet作为实际对象。当您遍历此集合时,值将以明确定义的顺序返回。

如果您使用java.util.HashSet,则订单取决于内部哈希函数,该函数几乎肯定不是词典(基于内容)。

答案 3 :(得分:11)

您可以使用TreeSet代替。

答案 4 :(得分:11)

Java 8的排序方式是:

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这是一个如何根据大小自然地对YourItem的HashSet进行排序的例子。

* Collectors.toList()将收集排序到List中的结果,您需要使用List<Foo> sortedListOfFoo =

来捕获它

答案 5 :(得分:5)

您可以使用Java 8收集器和TreeSet

list.stream().collect(Collectors.toCollection(TreeSet::new))

答案 6 :(得分:4)

您可以使用其他答案中提到的TreeSet。

以下是关于如何使用它的更详细说明:

TreeSet<String> ts = new TreeSet<String>();
ts.add("b1");
ts.add("b3");
ts.add("b2");
ts.add("a1");
ts.add("a2");
System.out.println(ts);
for (String s: ts)
    System.out.println(s);

输出:

[a1, a2, a3, a4, a5]
a1
a2
b1
b2
b3

答案 7 :(得分:2)

HashSet中的元素无法排序。每当你将元素放入HashSet时,它都会搞乱整个桶。它的好处是效率。

每次插入元素时,TreeSet都会自动对所有元素进行排序。

也许,你要做的只是排序一次。在这种情况下,TreeSet不是最佳选择,因为它需要始终确定新添加元素的放置。

最有效的解决方案是使用ArrayList。创建一个新列表并添加所有元素,然后对其进行一次排序。如果你只想保留唯一的元素(删除像set一样的所有重复元素,然后将列表放入LinkedHashSet,它将保留你已经排序的顺序)

List<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);
Collections.sort(list);
Set<Integer> unique = new LinkedHashSet<>(list); // 4 5 6
// The above line is not copying the objects! It only copies references.

现在,如果您希望以列表形式将其转换为列表,那么您已经获得了一个有序集。

答案 8 :(得分:1)

1. Add all set element in list -> al.addAll(s);
2. Sort all the elements in list using -> Collections.sort(al);


 public class SortSetProblem {
 public static void main(String[] args) {
    ArrayList<String> al = new ArrayList();
    Set<String> s = new HashSet<>();
    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);
    }
  }
 }
  

输入 - ved prakash sharma apple ved banana

     

输出 - apple banana prakash sharma ved

答案 9 :(得分:1)

如果您希望结尾Collection的形式为Set,并且要定义自己的natural order而不是TreeSet,则-< br />
1.将HashSet转换为List
2.使用List自定义对Comparator的排序
3.将List转换回LinkedHashSet以维持顺序
4.显示LinkedHashSet

示例程序-

package demo31;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class App26 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        addElements(set);
        List<String> list = new LinkedList<>();
        list = convertToList(set);
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int flag = s2.length() - s1.length();
                if(flag != 0) {
                    return flag;
                } else {
                    return -s1.compareTo(s2);
                }
            }
        });
        Set<String> set2 = new LinkedHashSet<>();
        set2 = convertToSet(list);
        displayElements(set2);
    }
    public static void addElements(Set<String> set) {
        set.add("Hippopotamus");
        set.add("Rhinocerous");
        set.add("Zebra");
        set.add("Tiger");
        set.add("Giraffe");
        set.add("Cheetah");
        set.add("Wolf");
        set.add("Fox");
        set.add("Dog");
        set.add("Cat");
    }
    public static List<String> convertToList(Set<String> set) {
        List<String> list = new LinkedList<>();
        for(String element: set) {
            list.add(element);
        }
        return list;
    }
    public static Set<String> convertToSet(List<String> list) {
        Set<String> set = new LinkedHashSet<>();
        for(String element: list) {
            set.add(element);
        }
        return set;
    }
    public static void displayElements(Set<String> set) {
        System.out.println(set);
    }
}

输出-

[Hippopotamus, Rhinocerous, Giraffe, Cheetah, Zebra, Tiger, Wolf, Fox, Dog, Cat]

此处收藏集已排序为-

第一-长度String的降序
其次-String字母层次结构的降序

答案 10 :(得分:1)

在我的拙见中,LazerBanana的答案应该是评分最高的答案,并且因为所有其他指向java.util.TreeSet的答案(或先转换为列表,然后在转换后的列表中调用Collections.sort(...))都被接受了”麻烦问问OP HashSet是什么样的对象,即那些元素是否具有预定义的自然顺序,这不是可选问题,而是必填问题。

如果元素类型尚未实现HashSet接口,或者您没有显式传递{{,那么您就不能进入并将TreeSet元素放入Comparable中1}}到Comparator的构造函数。

来自TreeSet JavaDoc,

  

构造一个新的空树集,根据自然排序   其元素的顺序。插入集合中的所有元素必须   实现Comparable接口。此外,所有这些元素   必须可以相互比较:e1.compareTo(e2)不能抛出   集合中任何元素e1和e2的ClassCastException。如果用户   尝试向集合添加违反此约束的元素   (例如,用户尝试将字符串元素添加到其   元素是整数),则add调用将引发ClassCastException。

这就是为什么只有所有基于Java8流的答案(在此定义您的比较器)才有意义的原因,因为在POJO中实现可比性是可选的。程序员在需要时定义比较器。尝试不提出基本问题而收集到TreeSet中也是错误的(忍者的答案)。假设对象类型为TreeSetString也是不正确的。

话虽如此,其他问题如

  1. 排序效果
  2. 存储足迹(每次整理或希望就地对集进行排序等时,保留原始集并创建新的排序集)

也应该是其他相关点。仅仅指向API并不是唯一的意图。

由于原始集仅包含 unique 元素,并且该约束也由排序集维护,因此由于数据重复,因此需要从内存中清除原始集。

答案 11 :(得分:0)

只要您不想使用TreeSet,就可以尝试一下。

set = set.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new));

答案 12 :(得分:0)

根据@LazerBanana给出的答案,我将放置一个自己的示例集,该集按对象的ID排序:

Set<Clazz> yourSet = [...];

yourSet.stream().sorted(new Comparator<Clazz>() {
    @Override
    public int compare(Clazz o1, Clazz o2) {
        return o1.getId().compareTo(o2.getId());
    }
}).collect(Collectors.toList()); // Returns the sorted List (using toSet() wont work)

答案 13 :(得分:0)

答案 14 :(得分:0)

我们无法确定HashSet的元素会自动排序。但我们可以通过转换为TreeSet或任何List(如ArrayList或LinkedList等)来对它们进行排序。

// Create a TreeSet object of class E
TreeSet<E> ts = new TreeSet<E> ();

// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);

System.out.println(ts.toString() + "\t Sorted Automatically");

答案 15 :(得分:0)

您可以将guava库用于相同的

Set<String> sortedSet = FluentIterable.from(myHashSet).toSortedSet(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // descending order of relevance
        //required code
    }
});

答案 16 :(得分:0)

您可以通过以下方式执行此操作:

方法1:

  1. 创建一个列表并将所有hashset值存储到其中
  2. 使用Collections.sort()
  3. 对列表进行排序
  4. 将列表存储回LinkedHashSet,因为它保留了广告订单
  5. 方法2:

    • 创建一个treeSet并将所有值存储到其中。

    方法2更为可取,因为另一种方法在hashset和list之间来回传输数据会耗费大量时间。

答案 17 :(得分:-1)

您可以像这样将其包装在TreeSet中:

Set mySet = new HashSet();
mySet.add(4);
mySet.add(5);
mySet.add(3);
mySet.add(1);
System.out.println("mySet items "+ mySet);   

TreeSet treeSet = new TreeSet(mySet);   
System.out.println("treeSet items "+ treeSet);   

输出:
mySet项目[1、3、4、5]
treeSet项目[1、3、4、5]

Set mySet = new HashSet();
mySet.add("five");
mySet.add("elf");
mySet.add("four");
mySet.add("six");
mySet.add("two");
System.out.println("mySet items "+ mySet);

TreeSet treeSet = new TreeSet(mySet);
System.out.println("treeSet items "+ treeSet);

输出:
mySet项目[六个,四个,五个,两个,小精灵]
treeSet项目[elf,五个,四个,六个,两个]

此方法的要求是集合/列表的对象应具有可比性(实现Comparable接口)

答案 18 :(得分:-4)

这个简单的命令对我有用:

myHashSet.toList.sorted

我在print语句中使用了这个,所以如果你需要实际保持排序,你可能需要使用TreeSets或这个线程上提出的其他结构。