【问题标题】:Java data structureJava数据结构
【发布时间】:2011-05-19 15:05:23
【问题描述】:

我需要一些可以从标准集合或使用番石榴构建的数据结构。所以它应该是可变的Map<Enum, V>。其中V 是非常有趣的结构。

V 要求:

  • 可变
  • 按比较器排序(允许使用 compare(a, b) == 0 等元素) - 这些是迭代的需要
  • 设置(没有这样的ab,即a.equals(b) == true)- 可选

地图的额外可选要求

  • 键应按其自然顺序迭代

现在是 HashMap<SomeEnum, LinkedList<Entity>>,代码中有不同的内容,例如 collections.sort()

谢谢。

【问题讨论】:

    标签: java collections map guava


    【解决方案1】:

    示例实现

    这是您需要的类的Guava Multimap 实现:

    首先是缺点:它必须驻留在包com.google.common.collect 中。番石榴的制造者以其无限的智慧使AbstractSortedSetMultimap 包作用域。

    我将在所有示例中使用 enum

    public enum Color{
        RED, BLUE, GREEN
    };
    

    构造类

    有六个构造函数:

    • 空(使用HashMap 和自然排序的值)

      SortedSetMultimap<Color,String> simple = 
          new EnumValueSortMultiMap<Color, String>();
      
    • 使用Comparator(V)(使用HashMap&lt;K,SortedSet&lt;V&gt;&gt; 和提供的值比较器)

      SortedSetMultimap<Color,String> inreverse =
          new EnumValueSortMultiMap<Color, String>(
              Ordering.natural().reverse()
          );
      
    • 带有Map&lt;K,SortedSet&lt;V&gt;&gt;(如果您想对键进行排序,请使用它,传入SortedMap 实现)

      SortedSetMultimap<Color,String> withSortedKeys = 
          new EnumValueSortMultiMap<Color, String>(
              new TreeMap<Color, Collection<String>>()
          );
      
    • 带有Map&lt;K,SortedSet&lt;V&gt;&gt;Comparator&lt;V&gt;(与上面相同,但使用自定义比较器对值进行排序)

      SortedSetMultimap<Color,String> reverseWithSortedKeys = 
          new EnumValueSortMultiMap<Color, String>(
              new TreeMap<Color, Collection<String>>(),
              Ordering.natural().reverse()
          );
      
    • 使用Class&lt;K extends Enum&lt;K&gt;&gt;(在内部使用EnumMap 以提高效率,值的自然排序)

      SortedSetMultimap<Color,String> withEnumMap =
          new EnumValueSortMultiMap<Color, String>(
              Color.class
          );
      
    • 带有Class&lt;K extends Enum&lt;K&gt;&gt;Comparator&lt;V&gt;(与上面相同,但使用自定义比较器对值进行排序)

      SortedSetMultimap<Color,String> reverseWithEnumMap =
          new EnumValueSortMultiMap<Color, String>(
              Color.class, Ordering.natural().reverse()
          );
      

    源代码

    课程如下:

    package com.google.common.collect;
    
    import java.util.Collection;
    import java.util.Comparator;
    import java.util.EnumMap;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.SortedSet;
    import java.util.TreeSet;
    
    public class EnumValueSortMultiMap<K extends Enum<K>,
        V extends Comparable<? super V>>
        extends AbstractSortedSetMultimap<K, V>{
    
        private static final long serialVersionUID = 5359491222446743952L;
    
        private Comparator<? super V> comparator;
        private Class<K> enumType;
    
        public EnumValueSortMultiMap(){
            this(new HashMap<K, Collection<V>>());
        }
    
        public EnumValueSortMultiMap(final Comparator<? super V> comparator){
            this(new HashMap<K, Collection<V>>(), comparator);
        }
    
        public EnumValueSortMultiMap(final Map<K, Collection<V>> map){
            this(map, Ordering.natural());
        }
    
        public EnumValueSortMultiMap(final Map<K, Collection<V>> map,
            final Comparator<? super V> comparator){
            super(map);
            this.comparator = comparator;
        }
    
        public EnumValueSortMultiMap(final Class<K> enumClass,
            final Comparator<? super V> comparator){
            this(new EnumMap<K, Collection<V>>(enumClass), comparator);
        }
    
        public EnumValueSortMultiMap(final Class<K> enumClass){
            this(new EnumMap<K, Collection<V>>(enumClass));
        }
    
        @Override
        Map<K, Collection<V>> backingMap(){
            return new EnumMap<K, Collection<V>>(enumType);
        }
    
        @Override
        public Comparator<? super V> valueComparator(){
            return comparator;
        }
    
        @Override
        SortedSet<V> createCollection(){
            return new TreeSet<V>(comparator);
        }
    
    }
    

    其他方法

    更新:我想正确的 Guava 方法应该是这样的(它使用我写的 SortedArrayListin my other answer):

    public static <E extends Enum<E>, V> Multimap<E, V> getMap(
        final Class<E> clz){
    
        return Multimaps.newListMultimap(
            Maps.<E, Collection<V>> newEnumMap(clz),
            new Supplier<List<V>>(){
                @Override
                public List<V> get(){
                    return new SortedArrayList<V>();
                }
            }
        );
    }
    

    【讨论】:

    • 非常感谢。可能,我会使用它。如果在这个答案之后 Kewin 会改变 AbstractSortedSetMultimap 的范围,那将是完美的)
    • 我猜他们最终会的。我的猜测是他们还没有将自己提交给 API,所以他们只是公开了实现类。
    • @S.P.Floyd - seanizer,我希望它会。
    • @Stas:如果他们不改变范围,你可以在你的项目中创建一个名为“com.google.common.collect”的包并添加类。我试过了,它对我有用.
    • @S.P.Floyd - seanizer,你做得很好。所以谢谢你)
    【解决方案2】:

    如果一个额外的类太多,你可能想使用类Multimaps的工厂方法。

    SortedSetMultimap<Color, Entity> set = Multimaps.newSortedSetMultimap(
        new HashMap<Enum, Collection<Entity>>(), 
        new Supplier<TreeSet<Entity>>() {
            @Override
            public TreeSet<Entity> get() {
                return new TreeSet<Entity>(new Comparator<Entity>() {
                    @Override
                    public int compare(Entity o1, Entity o2) {
                        //TODO implement
                    }
                });
            }
    });
    

    【讨论】:

    • 总结得非常好。
    【解决方案3】:

    您可以使用EnumMap 代替当前的HashMapEnumMaps 对于枚举键更有效。在番石榴中检查Multimap [examples]。

    【讨论】:

    • EnumMap 是个好主意(+1),但问题是这不允许空构造函数。需要枚举类。
    【解决方案4】:

    你需要一个这样使用的集合实现 V:HashMap。上述要求影响 V(而非实体)。对吧?

    我认为link TreeSet<E> 应该满足您的要求:

    • TreeSet 实现了 Set 接口
    • 按自然顺序或自定义比较器排序
    • 可以添加和删除元素

    【讨论】:

    • 是的。我先用它实现它)但是TreeSet不能包含compare(a, b) == 0这样的元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多