如何根据值对Hashmultimap进行排序?

时间:2014-07-14 23:44:34

标签: java sorting guava

我在我的代码中使用HashMultiMap。我的HashMultiMap结构就像,

HashMultimap<String, Integer> map = HashMultimap.create();

map.put("a", 3);
map.put("m", 5);
map.put("l", 1);

System.out.println(map);

实际输出:{a = [3],l = [1],m = [5]}

现在,我想根据价值对其进行排序:

目标输出:{m = [5],a = [3],l = [1]}

1 个答案:

答案 0 :(得分:1)

如果你真的想对值进行排序,那么解决方案就是扩展ForwardingSortedSetMultimap并委托给TreeMultimap。

下面的示例要求Keys和Values实现Comparable,但可以轻松修改类以支持提供的Key和Value Comparators。

public class SortedValueTreeMultimap<K extends Comparable<K>, V extends Comparable<V>> extends
        ForwardingSortedSetMultimap<K, V> {

    private final Ordering<Map.Entry<K, Collection<V>>> mapEntryOrdering = new Ordering<Map.Entry<K, Collection<V>>>() {

        @Override
        public int compare(final Entry<K, Collection<V>> left, final Entry<K, Collection<V>> right) {

            // Safe as we cannot have nulls or empties
            return ComparisonChain.start()
                .compare(left.getValue()
                    .iterator()
                    .next(), right.getValue()
                    .iterator()
                    .next())
                .compare(left.getKey(), right.getKey())
                .result();

        }
    };

    public final Ordering<Entry<K, V>> entryOrdering = new Ordering<Map.Entry<K, V>>() {

        @Override
        public int compare(final Entry<K, V> left, final Entry<K, V> right) {

            return ComparisonChain.start()
                    .compare(left.getValue(), right.getValue())
                    .compare(left.getKey(), right.getKey())
                    .result();
        }

    };

    public final Comparator<Entry<K, V>> entryOrderingReverse = Collections.reverseOrder(this.entryOrdering);

    private final SortedSetMultimap<K, V> delegate = TreeMultimap.create();

    @Override
    protected SortedSetMultimap<K, V> delegate() {

        return this.delegate;
    }

    @Override
    public Set<Entry<K, V>> entries() {
        return FluentIterable.from(super.entries())
            .toSortedSet(this.entryOrdering);

    }

    public Set<Entry<K, V>> reverseEntries() {
        return FluentIterable.from(super.entries())
                .toSortedSet(this.entryOrderingReverse);
    }

    @Override
    public String toString() {
        return FluentIterable.from(this.asMap()
            .entrySet())
            .toSortedSet(this.mapEntryOrdering)
            .toString();

    }

    public static void main(final String... args) {

        final SortedValueTreeMultimap<String, Integer> sortedMap = new SortedValueTreeMultimap<String, Integer>();

        sortedMap.put("a", 7);
        sortedMap.put("a", 3);
        sortedMap.put("a", 7);
        sortedMap.put("m", 5);
        sortedMap.put("m", 4);
        sortedMap.put("m", 4);
        sortedMap.put("k", 1);
        sortedMap.put("j", 1);

        // [j=[1], k=[1], m=[4, 5], a=[7]]
        System.out.println(sortedMap);

        // [j=1, k=1, a=3, m=4, m=5, a=7]
        System.out.println(sortedMap.entries());

        // [a=7, m=5, m=4, a=3, k=1, j=1]
        System.out.println(sortedMap.reverseEntries());
    }
}