我创建了以下结构,它将唯一的double值映射到一对或多对整数:
@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 :(得分:5)
首先使用一对整数对的类。或者这是巧合,所有数组都包含一堆对吗?
第二件事是,可以从配置文件中读取这些初始化数据。
编辑:当我再次查看此代码时,我意识到双打作为地图中的键有些冒险。如果由于数学运算而产生双打,则不清楚它们是否与计算机相等(即使它们在数学意义上相等)。浮点数表示为计算机中的近似值。您很可能希望将值与间隔(示例0.0-0.3)相关联,而不是值本身。如果始终使用与数组中的键相同的常量,则可以避免麻烦。但是在这种情况下你也可以使用枚举,如果他将计算出的双精度数用作地图中的键,那么没有新的程序员遇到麻烦。
答案 1 :(得分:2)
创建另一个类来保存整数对,并使用列表存储它们:
Map<Double,List<MyPair>>
这些是任意的整数对,还是代表什么?如果是后者,那么恰当地命名。新类在Java中很便宜,良好的命名会降低维护成本。
编辑:为什么要创建HashMap的匿名子类?
答案 2 :(得分: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
}
答案 3 :(得分:0)
你可以在Integer [] []周围打一个类,比如Point?
这会让你有一个
HashMap<Double, List<Point>>
答案 4 :(得分: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或其他指定对象,它可能会清理您的界面。因此,更具体地“输入”您的整数数组。
答案 5 :(得分:0)
你也可以尝试使用Builder;对于这种用途,Java并不像其他语言那样好......但是这里是FYI:
第一次曝光
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();
第二次拍摄
为了激活最终的“build()”调用和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的问题
答案 6 :(得分:0)
你在这里做的并不多。警告必须被压制;在实践中,除非您实际上计划序列化此对象,否则您永远不必担心serialVersionUID
。
拳击可以(也可能应该)使用类型集合删除,如此处其他答案中所述。要删除样板,您必须使用方法。例如:
private static void put (double key, int x, int y) {
rules.put(key, new Point(x,y));
}