2009-04-21 105 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)); 
}