Having a Multimap sorted on keys only in Java

后端 未结 8 1235
北荒
北荒 2020-12-03 17:19

I would like to have a c.g.c.c.Multimap that is sorted based on keys only. The values shouldn\'t be sorted. I\'ve tried to build something with guava\'s T

相关标签:
8条回答
  • 2020-12-03 17:21

    Multimaps.index returns an ImmutableListMultimap, so you wouldn't be able to sort it after creating it. You could, however, first create a sorted copy of your Iterable<MyObject> and feed that to Multimap.index... ImmutableListMultimap keeps things in the same order it was given them.

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

    Another option might be to create a TreeMultimap and use Ordering.arbitrary() as the Comparator for the values.

    0 讨论(0)
  • 2020-12-03 17:23

    Best solution which always works for me is to use Multimap & TreeMultiMap. this will order results in ascending order on keys even if you have multiple duplicate keys. Solution below:

    Multimap<Double, Integer> map= TreeMultimap.create(Ordering.natural().reverse(),         Ordering.natural());
    
    if (!map.isEmpty()) {               
                    printMap(map);
                }
    
    public static <K, V> void printMap(Multimap<Double, Integer> map) throws Exception {
            for (Map.Entry<Double, Integer> entry : map.entries()) {
                System.out.println("Key : " + entry.getKey() 
                    + " Value : " + entry.getValue());              
            }
        }
    
    0 讨论(0)
  • 2020-12-03 17:26

    Call Multimaps.newMultimap, which gives you the flexibility to create, for example, a Multimap backed by TreeMap whose values are ArrayLists.

    0 讨论(0)
  • 2020-12-03 17:35

    I'd like to point out that the alternative proposed solution, namely "to create a TreeMultimap and use Ordering.arbitrary() as the Comparator for the values", only works if MyObject doesn't override equals() or hashcode(). Ordering.arbitrary() is inconsistent with equals and uses object identity instead, which makes it not a good idea to use it in conjunction with a TreeSet.

    0 讨论(0)
  • 2020-12-03 17:40

    Though the OP's specific situation seems to have been answered using immutable multimap building functions, I needed a mutable version of what he was asking for. In case it helps anyone, here's the generic method I ended up creating:

    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);
                }
            });
    }
    
    0 讨论(0)
  • 2020-12-03 17:42

    MultimapBuilder was introduced in Guava 16:

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

    That keeps your keys sorted by their natural order (MultimapBuilder::treeKeys is also overloaded to accept a custom comparator), and the values associated with each key are maintained in a LinkedList (ArrayList and HashSet are among the other options).

    0 讨论(0)
提交回复
热议问题