繁体   English   中英

排序哈希图Java键的有效方法

[英]Efficient way to sort keys of hashmap Java

给定一个hashMap并在arraylist中按排序顺序返回hashmap的键,这是函数API:

ArrayList<String> foo(HashMap<String,String> hashMap)
{
}

现在,有两种方法可以解决问题:

  1. 取得arraylist中的所有键,然后对其进行排序
  2. 将map键存储在树集中,然后存储在arraylist中并返回。

前一种方法不会使用额外的空间复杂度,因为我没有使用树集。 键是字母数字。 哪一个时间复杂度更低。 您会建议其他方式吗?

在某种程度上取决于您打算对事后进行“分类”处理。

但是,对于您而言,您是在说:最后,您需要一个排序列表; 因此:直接创建该列表,进行排序并返回!

即使两种方法都具有相同的复杂度(O(n * log(n))-请记住,对列表进行排序可能会更快(因为它只需要移动数组中的元素,而不必创建大量树节点)。

换句话说:创建该TreeList然后将其转换为ArrayList意味着可以确保进行大量复制。 只需避免这种情况!

答案将取决于密钥的域。 在某些情况下,按排序顺序(即,在树中)存储密钥非常有效。 但是,我建议在大多数情况下,对检索进行一次排序将更为有效。

我尝试了以下代码:

    Map<Integer, Integer> map = new HashMap<>();
    Random random = new Random();
    random.ints(1000000).forEach(n -> map.put(n, n));
    long time1 = System.currentTimeMillis();
    Set<Integer> set = new TreeSet<>(map.keySet());
    List<Integer> list1 = new ArrayList<>(set);
    long time2 = System.currentTimeMillis();
    List<Integer> list2 = new ArrayList<>(map.keySet());
    Collections.sort(list2);
    long time3 = System.currentTimeMillis();
    System.out.println("Set approach " + (time2 - time1));
    System.out.println("Sort approach " + (time3 - time2));

结果是3768和1824,我怀疑这在这两种方法中是相当典型的。

出于兴趣,我还尝试了:

   List<Integer> list3 = map.keySet().stream().sorted().collect(Collectors.toList());

结果为537毫秒:比Collections.sort方法快3倍以上。

但是,当我重试一千万个条目时,采用了三种方法

  • TreeSet为26,916
  • 2,845 for Collection.sort
  • 13,580 for Stream.sorted

结论是,对大型地图,对数组进行一次排序效率更高。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM