首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在Java中只对键进行排序的多映射

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

Stack Overflow用户
提问于 2011-03-31 22:29:16
回答 8查看 21.9K关注 0票数 25

我想有一个c.g.c.c.Multimap,这是排序的基础上只关键字。这些值不应该排序。我曾尝试用芭乐的TreeMultimap构建一些东西,但我不能使用它,因为值类型没有实现Comparable

代码语言:javascript
代码运行次数:0
运行
复制
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;
  }
}

我曾考虑过获取键的SortedSet,然后迭代排序集中的每个键以获取各种值,但我希望使用Guava中现有的(尚未发现的)特性,而不是使用这种hack。

注意:我不会让MyObject实现Comparable,因为它对我的实际对象没有任何意义。

输入/输出示例:

代码语言:javascript
代码运行次数:0
运行
复制
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());
}

打印:

代码语言:javascript
代码运行次数:0
运行
复制
1 -> c // or switched with line below
1 -> e
2 -> a
3 -> b // or switched with line below
3 -> d
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-03-31 23:07:32

Multimaps.index返回一个ImmutableListMultimap,因此您在创建它之后将无法对其进行排序。但是,您可以首先创建Iterable<MyObject>的排序副本,并将其提供给Multimap.index……ImmutableListMultimap会按给定的顺序保存内容。

代码语言:javascript
代码运行次数:0
运行
复制
public static ImmutableMultimap<Integer, MyObject> indexOnScore(Iterable<MyObject> i) {
  List<MyObject> sorted = Ordering.natural().onResultOf(myObjectToScore())
      .sortedCopy(i);
  return Multimaps.index(sorted, myObjectToScore());
}

另一种选择可能是创建一个TreeMultimap,并使用Ordering.arbitrary()作为值的Comparator

票数 22
EN

Stack Overflow用户

发布于 2014-07-10 19:08:11

在Guava 16中引入了MultimapBuilder

代码语言:javascript
代码运行次数:0
运行
复制
<K extends Comparable<? super K>, V> ListMultimap<K, V> multimap() {
    return MultimapBuilder.treeKeys().linkedListValues().build();
}

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

票数 17
EN

Stack Overflow用户

发布于 2011-11-04 07:33:59

虽然OP的特定情况似乎已经使用不可变的multimap构建函数得到了回答,但我需要一个他所要求的可变版本。如果它对任何人有帮助,下面是我最终创建的泛型方法:

代码语言:javascript
代码运行次数:0
运行
复制
static <K, V> Multimap<K, V> newTreeArrayListMultimap(
    final int expectedValuesPerKey)
{
    return Multimaps.newMultimap(new TreeMap<K, Collection<V>>(),
        new Supplier<Collection<V>>()
        {
            @Override
            public Collection<V> get()
            {
                return new ArrayList<V>(expectedValuesPerKey);
            }
        });
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5501468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档