2009-04-21 57 views
3

我创建了以下结构,独特的双值映射到一个或多个整数对:难看Java数据结构

@SuppressWarnings("boxing") 
    private static final HashMap<Double, Integer[][]> rules = 
     new HashMap<Double, Integer[][]>() { 
     private static final long serialVersionUID = 1L; 
     { 
      put(-0.6, new Integer[][] { { 1, 3 } }); 
      put(-0.3, new Integer[][] { { 2, 2 } }); 
      put(0.0, new Integer[][] { { 2, 4 }, { 3, 3 }, { 4, 2 } }); 
      put(0.3, new Integer[][] { { 4, 4 } }); 
      put(0.6, new Integer[][] { { 5, 3 } }); 
     } 
    }; 

我也可以重写此所以它更简单 - 即没有处理警告(serialVersionUID,装箱),它是如此冗长?

+0

什么是代码?这看起来像原始沉迷代码的气味。 – 2009-04-21 15:12:34

+0

这是一套用于视觉引导机器人运动的模糊逻辑控制器的简化规则。 – JRL 2009-04-21 15:45:57

+0

是否有任何理由使用Integer [] []而不是int [] []? – 2009-04-21 21:07:30

回答

5

对于整数对使用类应该是第一个。或者这是巧合,所有包含一堆对的数组?

第二件事情是,这些初始化数据可以从配置文件读取。

编辑:当我再次查看这段代码时,我意识到在一个Map中Doubles键是有点冒险的。如果你通过数学运算产生双精度数,那么它是否与计算机相等(即使它们在数学意义上是相等的)也是不清楚的。浮点数在计算机中表示为近似值。很可能你想将这些值与间隔(例如0.0-0.3)相关联,而不是该值本身。如果您始终使用与数组中的键相同的常量,则可能会避免麻烦。但在这种情况下,您也可以使用枚举,并且如果他使用计算的双精度值作为映射中的键,则不会有新程序员遇到麻烦。

2

再创建一个类来保存您的整数对,并使用列表存储它们:

Map<Double,List<MyPair>> 

难道这些是任意整数对,或将代表什么?如果是后者,则适当命名。 Java中的新类很便宜,而良好的命名将降低维护成本。

编辑:你为什么要创建一个HashMap的匿名子类?

0

使用静态初始化将在我看来稍微好一点,但它确实一无所知的详细程度:

private static final Map<Double, int[][]> rules; 

static { 
    rules = new HashMap<Double, int[][]>(); 

    rules.put(-0.6, new int[][] { { 1, 3 } }); 
    rules.put(-0.3, new int[][] { { 2, 2 } }); 
    rules.put(0.0, new int[][] { { 2, 4 }, { 3, 3 }, { 4, 2 } }); 
    rules.put(0.3, new int[][] { { 4, 4 } }); 
    rules.put(0.6, new int[][] { { 5, 3 } }); 

} 

采用了特殊的Pair类和Arrays.asList另一种选择:

class Pair<A, B> { 
    A a; 
    B b; 

    public Pair(A fst, B snd) { 
    } 

    // getters and setters here 
} 

private static final Map<Double, List<Pair<Integer, Integer>>> rules; 

static { 
    rules = new HashMap<Double, List<Pair<Integer, Integer>>>(); 

    rules.put(-0.6, Arrays.asList(new Pair(1, 3))); 
    rules.put(-0.3, Arrays.asList(new Pair(2, 2))); 
    rules.put(0.0, Arrays.asList(new Pair(2, 4), new Pair(3, 3), new Pair(4, 2)); 
    // etc 
} 
0

你能包装一个名为Integer [] []的类,称为Point?

这将使你有

HashMap<Double, List<Point>> 
0

我将与MultiValueMap开始。 http://larvalabs.com/collections/

这样,你可以这样做:

private static final MultiValueMap<Double, Integer[]> rules; 
    static { 
     MultiValueMap<Double, Integer[]> map = new MultiValueMap <Double, Integer[]>(); 

     map.put(-0.6, new Integer[] { 1, 3 }); 
     map.put(-0.3, new Integer[] { 2, 2 }); 
     map.put(0.0, new Integer[] { 2, 4 }, new Integer[]{ 3, 3 }, new Integer[]{ 4, 2 }); 
     map.put(0.3, new Integer[] { 4, 4 }); 
     map.put(0.6, new Integer[] { 5, 3 }); 
     rules = map; 
    }; 

它看起来也像你使用双整数作为密钥列表的跳投。如果您将其称为RulePair或其他指定对象,它可能会清理您的界面。这样可以更加特殊地“键入”Integer数组。

0

你也可以试试Builder;对于这种用途,Java不如其他语言。但这里是供参考:

第一枪

class RuleBuilder { 

    private Map<Double, Integer[][]> rules; 

    public RuleBuilder() { 
     rules = new HashMap<Double, Integer[][]>(); 
    } 

    public RuleBuilder rule(double key, Integer[]... rows) { 
     rules.put(key, rows); 
     return this; 
    } 

    public Integer[] row(Integer... ints) { 
     return ints; 
    } 

    public Map<Double, Integer[][]> build() { 
     return rules; 
    } 
} 

示例用法:

private static final Map<Double, Integer[][]> rules = 
       new RuleBuilder() {{ 
        rule(-0.6, row(1, 3));       
        rule(-0.3, row(2, 2)); 
        rule(0.0, row(2, 4), row(3,3), row(4, 2)); 
        rule(0.3, row(4, 4)); 
        rule(0.6, row(5, 3)); 
       }}.build(); 

第二杆

为了elimate最后的 “建立()” 呼叫和double brace init你可以尝试:

class RuleBuilder2 extends HashMap<Double, Integer[][]> { 

    public RuleBuilder2 rule(double key, Integer[]... rows) { 
     put(key, rows); 
     return this; 
    } 

    public Integer[] row(Integer... ints) { 
     return ints; 
    } 
} 
在这种情况下

的代码是一个好一点:

private static final Map<Double, Integer[][]> rules2 = 
       new RuleBuilder2(). 
        rule(-0.6, row(1, 3)). 
        rule(-0.3, row(2, 2)). 
        rule(0.0, row(2, 4), row(3,3), row(4, 2)). 
        rule(0.3, row(4, 4)). 
        rule(0.6, row(5, 3)); 

编辑

可能是我用不那么有意义的名称;盒装/非盒装转换仍然是一个问题,但这是一个问题Java

0

在这里没有太多的事情可以做。警告必须被压制;在实践中,除非实际上计划序列化此对象,否则不必担心serialVersionUID

拳击可以(也可能应该)通过使用类型集合中删除,如其他答案中所述。要移除样板,您必须使用方法。例如:

private static void put (double key, int x, int y) { 
    rules.put(key, new Point(x,y)); 
}