2012-01-25 51 views
1

我有以下地图:如何在Java中按值(ArrayList)大小对映射进行排序?

Map<String, List<String>> map = new HashMap<String, List<String>>(); 

这是充满了对键和值的。
例如:key =学生姓名和值=家庭成员姓名。
我想按照字符串列表的大小排序地图。我曾尝试使用TreeMap实现Comparator,但出现错误,因此我切换回HashMap。有任何想法吗?

+0

带比较器的'TreeMap'是要走IMO的路。你的错误是什么? – paislee

+0

为了强化其他答案的信息,你不能对HashMap(或者,一般来说,一个Map)进行排序。您必须使用支持排序的特定版本的Map。 TreeMap似乎是按值排序的最佳选择。 – madth3

+0

TreeMap按键排序,而不是值。 –

回答

3

您应该使用无序的HashMap,然后每次您要排序时,都将HashMap的所有值放入TreeMap中,并使用以HashMap作为变量的Comparator。

然后,对于您比较的每个键,您将获得HashMap(列表)的值并检查列表大小。所以你根据列表大小进行比较,根据情况返回-1,0或1。

一旦你完成了你所需要的,你就放弃了这个TreeMap。

如果您尝试仅使用TreeMap,那么您会看到您根据不是此键的属性的值来排序键。在这种情况下,值的长度(一个列表)。所以,可能存在一个增加列表长度的函数,并且TreeMap甚至不会注意到。

一些代码:

public class ListSizeComparator implements Comparator<String> { 

private final Map<String, List<String>> map; 

public ListSizeComparator(final Map<String, List<String>> map) { 
    this.map = map; 
} 

@Override 
public int compare(String s1, String s2) { 
    //Here I assume both keys exist in the map. 
    List<String> list1 = this.map.get(s1); 
    List<String> list2 = this.map.get(s2); 
    Integer length1 = list1.size(); 
    Integer length2 = list2.size(); 
    return length1.compareTo(length2); 
} 

} 
+0

我不确定我明白你的意思。你能详细说明比较方法是怎么样的吗? – Johny

+0

我已经添加了一个代码示例来说明我的观点。 – Luciano

+0

嘿,谢谢!我尝试了TreeMap > sorter = new TreeMap(new ListSizeComparator(map));但它不起作用。当我尝试打印地图时,我什么也没得到。 – Johny

0

我在这里看到三个选择:每次你都需要时间

  1. 排序地图内容 - 如果它不是过于频繁,它的确定。
  2. 除地图存储其他辅助结构与所需的顺序,例如TreeMap<Integer, List<String>>(关键 - 家庭成员的数量,学生的价值清单)。
  3. 可能你并不需要你所描述的所有地图,下面的地图就足够了:TreeMap<Integer, Map<String, List<String>>>(关键 - 家庭成员数量,价值 - 包含学生的家庭成员数量等于$的原始地图的一部分键)。
+0

我刚刚尝试过,但它不起作用,因为如果两个学生有相同数量的家庭成员,只有其中一个将被插入。我猜测键是在地图中独一无二的。 – Johny

+0

是的,钥匙是独一无二的。这就是为什么地图的值是案例2中的列表和案例3中的地图,这允许在顶层地图中的相同键下存储多个派生物。 –

2

解决方案是https://stackoverflow.com/a/8897384/869736或多或少相同,但所有你需要做的是写一个Comparator,通过它们的长度比较列表。

Comparator<List<String>> lengthComparator = new Comparator<List<String>>() { 
    public int compare(List<String> a, List<String> b) { 
    return a.size() - b.size(); 
    // size() is always nonnegative, so this won't have crazy overflow bugs 
    } 
}; 

然后就使用这里概述的解决方案。

+0

嘿谢谢!但这意味着我必须使用Guava库,对吧? – Johny

+0

是的,这确实如下。解决这个问题会让人感觉不太愉快,但仍然可以使用LinkedHashMap作为输出,Collections.reverseOrder而不是Ordering.reverse(),并且使用Ordering.sortedCopy()而不是Ordering.sortedCopy()进行显式复制和排序,还有一堆其他东东。 –

+0

Guava的藏品框架确实是非常有用的,而这只是其功能的一小部分。您可能会发现wiki(http://code.google.com/p/guava-libraries/wiki/GuavaExplained)很有帮助。 –

相关问题