Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
丑陋的java数据结构_Java_Data Structures - Fatal编程技术网

丑陋的java数据结构

丑陋的java数据结构,java,data-structures,Java,Data Structures,我创建了以下结构,将唯一的双精度值映射到一对或多对整数: @SuppressWarnings("boxing") private static final HashMap<Double, Integer[][]> rules = new HashMap<Double, Integer[][]>() { private static final long serialVersionUID = 1L; {

我创建了以下结构,将唯一的双精度值映射到一对或多对整数:

   @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 } });
         }
   };
@SuppressWarnings(“装箱”)
私有静态最终哈希映射规则=
新HashMap(){
私有静态最终长serialVersionUID=1L;
{
put(-0.6,新整数[][{{1,3}});
put(-0.3,新整数[][{{2,2}});
put(0.0,新整数[][{{2,4},{3,3},{4,2});
put(0.3,新整数[][{4,4});
put(0.6,新整数[][{{5,3});
}
};

我是否可以重写它以使其更简单—即不必处理警告(serialVersionUID、boxing),而且它非常冗长?

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

Map<Double,List<MyPair>>
Map
这些是任意的整数对,还是表示某种东西?如果是后者,则适当命名。新类在Java中很便宜,良好的命名将降低维护成本


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

在我看来,使用静态初始值设定项会稍微好一点,尽管它对详细性没有任何影响:

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 } });

}

你能把一个名为Point的整数[]类包装起来吗

那会让你有一个

HashMap<Double, List<Point>>
HashMap

我将从多值映射开始

通过这种方式,您可以:

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;
   };
私有静态最终多值映射规则;
静止的{
多值映射=新的多值映射();
put(-0.6,新整数[]{1,3});
put(-0.3,新整数[]{2,2});
put(0.0,新整数[]{2,4},新整数[]{3,3},新整数[]{4,2});
put(0.3,新整数[]{4,4});
put(0.6,新整数[]{5,3});
规则=地图;
};

看起来你也经常使用整数对作为键列表。如果您将其引用为规则对或其他指定对象,它可能会清理您的接口。因此,更具体地“键入”整数数组。

首先应该为整数对使用类。或者这是巧合,所有数组都包含一组对

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


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

您也可以尝试使用生成器;在这种用途上,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;
    }
}
类规则生成器{
私有地图规则;
公共规则生成器(){
rules=newhashmap();
}
公共规则生成器规则(双键,整数[]…行){
规则。放置(键,行);
归还这个;
}
公共整数[]行(整数…整数){
返回整数;
}
公共地图构建(){
退货规则;
}
}
示例用法:

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();
私有静态最终映射规则=
新规则生成器(){{
规则(-0.6,第(1,3)行);
规则(-0.3,第(2,2)行);
规则(0.0,第(2,4)行,第(3,3)行,第(4,2)行);
规则(0.3,第(4,4)行);
规则(0.6,第(5,3)行);
}}.build();
第二枪

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;
    }
}
为了省略最后的“build()”调用,您可以尝试:

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;
    }
}
类RuleBuilder2扩展了HashMap{
公共规则生成器2规则(双键,整数[]…行){
放置(键,行);
归还这个;
}
公共整数[]行(整数…整数){
返回整数;
}
}
在这种情况下,代码稍微好一点:

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));
私有静态最终映射规则2=
新建RuleBuilder2()。
规则(-0.6,第(1,3)行)。
规则(-0.3,第(2,2)行)。
规则(0.0,第(2,4)行,第(3,3)行,第(4,2)行)。
规则(0.3,第(4,4)行)。
规则(0.6,第(5,3)行);
编辑


也许我用过的名字没有那么有意义;装箱/未装箱转换仍然是一个问题,但这是Java的一个问题

在这里您可以做的不多。警告必须被压制;实际上,您永远不必担心
serialVersionUID
,除非您实际上计划序列化此对象

可以(也可能应该)通过使用此处其他答案中描述的类型化集合来删除装箱。要删除样板文件,必须使用一种方法。例如:

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

但为了避免警告,所有对都必须构造为新对(x,y)。在这种情况下,我更喜欢一双特制的。我忘了将类型参数添加到实例化中;一个特殊的pair类确实会更好。或者你可以添加一个
of
方法,这样你就有了
of(1,3)
或者甚至
of(1,3)
。代码是用来干什么的?这看起来像是原始的困扰代码气味。这是一组用于视觉引导机器人运动的模糊逻辑控制器的简化规则。是否有任何理由使用整数[]而不是int[]]?@Peter:没有,只是为了使用HashMap。@JRL:Peter Lawrey的意思是int[]]作为泛型参数是完全可以接受的,而且可以避免大量的自动装箱/