「基本」単位となる単位を 1 つ選択します (1 つは重量用、たとえばgr、もう 1 つは距離用、たとえばm )。次に、各値の変換比率を使用してメソッドtoBaseUnit
と列挙型を追加します。fromBaseUnit
「if」は関係なく、変換方法は次のようになります。
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を使用しました。