选择其中一种单位作为“基本”单位(一种用于重量,例如gr;另一种用于距离,例如m)。然后使用每个值的转换率添加方法toBaseUnit
和枚举。fromBaseUnit
不涉及“ifs”,您的转换方法将如下所示:
ResultingUnit.fromBaseUnit(originalUnit.toBaseUnit(value));
示例枚举:
public enum Distance {
METER(new BigDecimal("1.0")), // Base Unit is METER
KM(new BigDecimal("1E3")),
CM(new BigDecimal("1E-2"));
private final static MathContext MC =
new MathContext(30, RoundingMode.HALF_EVEN);
private final BigDecimal conversionRatio;
Distance(BigDecimal conversionRatio) {
this.conversionRatio = conversionRatio;
}
long fromBaseUnit(BigDecimal baseUnit) {
return baseUnit.divide(conversionRatio, MC).longValue();
}
// returns BigDecimal to avoid rounding two times
// and possible division by zero
BigDecimal toBaseUnit(long originalUnit) {
return BigDecimal.valueOf(originalUnit).multiply(conversionRatio);
}
}
以及适应的转换方法:
public long metricConvLength(long value, Distance orgUnit, Distance resultUnit) {
return resultUnit.fromBaseUnit(orgUnit.toBaseUnit(value));
}
除了稍微快一点(通过避免Map
查找和遍历枚举值)之外,这种方法的主要优点是,如果您需要更复杂的转换操作(例如,Temperature
带有摄氏度、华氏温度和开尔文的枚举),您可以覆盖fromBaseUnit
并toBaseUnit
在枚举值主体。
工作示例。
我使用BigDecimal进行转换比率和内部计算,以便更好地控制精度和舍入行为。