仅在 Java 中对键进行排序的多映射

2022-09-01 16:54:13

我希望有一个仅根据键排序的。不应对值进行排序。我试图用番石榴构建一些东西,但我不能使用它,因为值类型没有实现。c.g.c.c.MultimapTreeMultimapComparable

public class MyObject /* doesn't implement Comparable */ {
  private String name;
  private int score;
  // Getters/setters are implemented
  public static Function<MyObject,Integer> myObjectToScore {
    @Override public Integer apply (MyObject o) { return o.score; }
  }
  public static Multimap<Integer,MyObject> indexOnScore(Iterable<MyObject> i) {
    Multimap<Integer,MyObject> m = Multimaps.index(i, myObjectToScore());
    // Do the sort of the keys.
    return m;
  }
}

我考虑过获取一个密钥,然后迭代排序集中的每个密钥以获取各种值,但我希望使用Guava中现有的(尚未发现的)功能,而不是使用这种黑客SortedSet

注意:我不会实现,因为它对我的实际对象没有意义。MyObjectComparable


输入/输出示例:

Set<MyObject> s = Sets.newHashSet(
  new MyObject("a", 2),
  new MyObject("b", 3),
  new MyObject("c", 1),
  new MyObject("d", 3),
  new MyObject("e", 1)
); // Assuming constructor MyObject(String name, int score)

for (Map.Entry<Integer, MyObject> e: MyObject.indexedOnScore(s).entries()) {
  System.out.printf("%d -> %s%n", e.getKey(), e.getValue().getName());
}

指纹:

1 -> c // or switched with line below
1 -> e
2 -> a
3 -> b // or switched with line below
3 -> d

答案 1

Multimaps.index返回 一个 ,因此在创建它后将无法对其进行排序。但是,您可以先创建您的排序副本并将其提供给... 使事物保持与给定顺序相同的顺序。ImmutableListMultimapIterable<MyObject>Multimap.indexImmutableListMultimap

public static ImmutableMultimap<Integer, MyObject> indexOnScore(Iterable<MyObject> i) {
  List<MyObject> sorted = Ordering.natural().onResultOf(myObjectToScore())
      .sortedCopy(i);
  return Multimaps.index(sorted, myObjectToScore());
}

另一种选择可能是创建 一个并用作值。TreeMultimapOrdering.arbitrary()Comparator


答案 2

MultimapBuilder在番石榴16中引入:

<K extends Comparable<? super K>, V> ListMultimap<K, V> multimap() {
    return MultimapBuilder.treeKeys().linkedListValues().build();
}

这将使您的键按其自然顺序排序(也重载以接受自定义比较器),并且与每个键关联的值保留在( 中,并且是其他选项之一)。MultimapBuilder::treeKeysLinkedListArrayListHashSet


推荐