【问题标题】:Sort a TreeMap by either Key Or Value按键或值对 TreeMap 进行排序
【发布时间】:2014-05-12 14:32:07
【问题描述】:

情况:

我有一个Map,更准确地说是一个TreeMap,看起来像

TreeMap<String, Integer>

我必须能够以升序或降序的方式对键或值进行排序。结果必须是Map 喜欢

Map<String, Integer>

不是ArrayList 或类似的东西,因为我的代码的其余部分(阅读:分配)将不再工作。我已经搜索过,但找不到任何适合我需要的东西。这甚至可能吗?双精度值不会丢失。

【问题讨论】:

  • 您可以编写自己的 Map 实现,允许您按值排序。据我所知,这样的事情是不存在的。您的自定义实现可以保留按值排序的树中项目的索引,以便快速检索。
  • *.com/questions/1448369/…>
  • 你是什么意思 - 双值可能不会丢失。?你的意思是重复值吗?还有一点不清楚的是,如果你的所有代码都是针对MapTreeMap 编写的。

标签: java sorting map treemap


【解决方案1】:

如果您使用两个相互支持的 BiMap,那么您实际上拥有一张地图。 有点像:

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

private BiMap<Integer, String> localid = HashBiMap.create();
private BiMap<String, Integer> inverse = localid.inverse();

您可以将每个引用、localid 和 inverse 视为它们自己的映射,但对其中一个的更改会反映在另一个中。唯一的缺点是现在键和值都必须是唯一的,因为其中一个的值是另一个的键。在大多数情况下,这不是问题。

为了对其进行排序,您可以随时制作一个本地副本,该副本是一个 treeMap,它会强制执行排序。例如。

ImmutableMap.copyOf(Maps.newTreeMap(bimap))

现在,如果您从未对地图进行更改,这将提供一个排序视图,您可以通过任何一种方式来完成。

编辑:TreebasedTable 的每个值都有两个键,您可以使用比较器对任一键集进行排序。我不确定这是否正是您所需要的,因为键集是独立的,但您可以稍微重构代码以使其成为可行的解决方案。

【讨论】:

  • +1 表示TreeBasedTable。然后你可以有一个Table&lt;String, Integer, Void&gt; 或其他任何东西,并获得对行或列的免费排序。
  • 是的,但是我可以有效地从给定的字符串获取给定的整数吗?我不确定,但与我经常使用的 BiMap 相比,我有点陌生。
  • 嗯,现在我仔细观察,我发现没有办法按列获得排序视图,只能按行。
  • getRowMap 和 getColumnMap 都返回排序后的地图,但它们并不能完全解决问题。 TreeBasedTable 就像一个矩阵,其中一个值由两个键标识。因此,getRowMap 独立于其列值返回具有给定行值的所有条目,并且是按列值排序的映射。但这并不是 OP 所要求的——但它可以通过拥有一个对象 All 来工作,因此 rowMap(All) 获取按列集排序的所有值。只是感觉不太对劲。
【解决方案2】:

如果地图很小并且对其进行迭代是一种不常见的操作,一种解决方案是只使用HashMap(以提高查找速度),然后在每次迭代时对条目进行排序。

另一种解决方案,如果与直接映射查找相比,您经常进行这些迭代,并且如果值(而不仅仅是键)是唯一的,则将维护两个排序映射,一个 &lt;String, Integer&gt; 和一个 &lt;Integer, String&gt;

【讨论】:

  • 这里要理解的一个关键点是,使用TreeMap 意味着地图按排序顺序存储,但任何地图都可以迭代 按排序顺序(只需将条目复制到列表中并在迭代之前对其进行排序)。
【解决方案3】:

Guava 具有BiMap 的概念。这就是你要找的吗?

【讨论】:

    【解决方案4】:

    TreeMap 的键按其可比性排序。

    【讨论】:

    • 如果您使用了正确的 its,这将是正确的,但它不能回答问题。
    【解决方案5】:

    尝试排序地图

    进一步提供其键的总排序的 Map。映射是根据其键的自然顺序排序的,或者由通常在排序映射创建时提供的比较器排序。此顺序在遍历已排序地图的集合视图(由 entrySet、keySet 和 values 方法返回)时反映出来。提供了几个额外的操作来利用排序。 (这个接口是SortedSet的map类比。)

    【讨论】:

    • 他已经在使用SortedMapTreeMap SortedMap。他还需要能够根据值对其进行排序,而 SortedMap 不这样做。