我想编写一个可以将一个单元转换为另一个单元的程序。假设我有2种方法。第一种方法可以做度量转换,第二种方法可以做权重转换。例如;
1。 long km=metricConvLength(long mil,Enum.mil,Enum.km);//first method
2。 long agirlik=metricConvWeight(long kg,Enum.mil,Enum.km);//second method
我想对这些变量使用 Enum 结构。 我的程序可以转换这些东西和对立面;
我的问题:我不想使用if-else
或switch-case
结构进行转换。(因为如果我使用if-else结构,我的代码看起来像这样如果我使用这些结构,那么我需要超过50个if-else结构。这是研究。)
我可以在不使用if-else或switch-case的情况下为这些转换编写算法。 我的目的是减少代码,减少工作量。有关算法的任何提示吗?
答案 0 :(得分:10)
您不需要if-then-else
- 实际上,您的程序中不需要控制语句。您所需要的只是一个查找表 - Map
可将您的单位枚举转换为double
转换因子,以便将度量单位乘以您获得的空间单位米的转换因子,以及千克对于重量单位。相反,按该因子划分米可以得到所需的单位。
掌握了这张地图后,您可以对所有单位对进行转换:
Cs
Cd
value * Cs / Cd
作为结果。例如,假设您要处理米,码,英寸和英尺。你的地图看起来像这样:
现在假设您要将7.5
码转换为英尺:
Cs = 0.9144
Cd = 0.3048
Res = 7.5 * 0.9144 / 0.3048 = 22.5
答案 1 :(得分:2)
我建议引入一种类型" MetricValue"。软件工程的历史充满了程序员忘记了他们使用的价值单位的项目。由此产生的灾难是众所周知的。
此外,我会提出一个不可变类,因为它使许多设计方面更简单。
在首次将所有值转换为基本单位然后将值转换为目标单位时,定义基本单位会对您有很大帮助。您也可以应用矩阵,但是您需要预先计算值。矩阵的大小将为n ^ 2,而从基本单位到基本单位的转换仅保留n个值。如果您使用耗费资源的复杂转换公式,那么它是有道理的。否则,这些努力的好处(太小)将会很小。
这段代码怎么样?
public class MetricValue {
public static enum Unit {
m(1.0d), y(0.9144d), in(0.0254d), ft(0.3048d);
final static Unit baseUnit = m;
final double perBaseUnit;
private Unit(double inM) {
this.perBaseUnit = inM;
}
public double fromBaseUnit(double value) {
return value / perBaseUnit;
}
public double toBaseUnit(double value) {
return value * perBaseUnit;
}
}
final double value;
final Unit unit;
public MetricValue(double value, Unit unit) {
super();
this.value = value;
this.unit = unit;
}
public MetricValue to(Unit newUnit) {
Unit oldUnit = this.unit;
return new MetricValue(newUnit.fromBaseUnit(oldUnit.toBaseUnit(value)),
newUnit);
}
@Override
public String toString() {
return value + " " + unit.name();
}
public static void main(String[] args) {
MetricValue distanceInM = new MetricValue(1, Unit.m);
MetricValue distanceInFt = new MetricValue(6, Unit.ft);
System.out.println(distanceInM);
System.out.println(distanceInM.to(Unit.y));
System.out.println(distanceInM.to(Unit.y).to(Unit.m));
System.out.println(distanceInM.to(Unit.y).to(Unit.ft));
System.out.println(distanceInFt.to(Unit.m));
}
}
您可以在计算时使用原始值并创建新的指标值。您还可以为基本或复杂的算术运算添加操作。
这里省略了吸气剂。
答案 2 :(得分:1)
将它们的相对值与你的枚举中的变量相关联(我猜你有一个用于距离,一个用于权重),如enum Distances { CM(100), M(100*1000), IN(254) }
,...然后你只需得到所提供值的比率,乘以通过第一个参数,你得到了你的结果。如果您想要一个合适的精度,请使用基础100或1000作为最小单位。
答案 3 :(得分:1)
选择其中一个单位作为“基础”单位(一个用于重量,例如 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
枚举使用Celsius,Farenheit和Kelvin),您可以覆盖枚举值正文中的fromBaseUnit
和toBaseUnit
。
我已将BigDecimal用于转换率和内部计算,以便更好地控制精度和舍入行为。
答案 4 :(得分:1)
在您的枚举中,您可以在枚举类型上实现fromString方法,假设您的枚举名称为“距离”
private static final Map<String,Distances> stringToEnum = new HashMap<String,Distances>;
初始化地图:
static{
for(Distances distance: values()) {
stringToEnum.put(distance.toString(),distance);
}
}
返回字符串的enumType:
public static Distances getDistance(String stringValue){
return stringToEnum.get(stringValue);
}
在您的方法中,您可以直接传入:
Distance.getDistance("feet").getCalculatedDistance()