0

我正在为 android 应用程序构建一个 java 单位转换器。我为用户提供了许多不同的单位转换,最终可能有 220 次总转换,如果只计算一个方向,则为 110。IE 米 -> 英尺和英尺 -> 米将是两种不同的转换。

截至目前,我正计划为每次转换编写小方法,总共 220 个(我认为这可能是最简单的方法,即使认为这需要一些时间)。现在我的问题是,一旦我设置了 2 个变量(convertFrom 和 convertTo),我想知道是否可以动态调用正确的方法?我可以只创建 if/else if 块,但这最终会变成大量的代码,并且希望有更好的方法来根据上面提到的 2 个变量调用正确的方法。有什么建议吗?

PS 抱歉,这里没有代码,我才刚刚开始,目前正处于计划阶段。

4

3 回答 3

0

如何使用将每个单位转换为一个标准测量单位的枚举。然后您可以调用 convert 将标准测量单位转换为新单位!

public enum UnitOfMeasure {
    // look at the constructor for the meaning
    // of the parameter
    UNIT1 (1.01),
    UNIT2 (1.02),
    // ...
    UNITX (2.00);

    // conversionFactor will convert each UNIT
    // type to your favorite UnitOfMeasure
    private final double conversionFactor;
    UnitOfMeasure(double conversionFactor) {
        this.conversionFactor = conversionFactor;
    }

    // have a constant for every unit type
    // to choose which unit to convert to
    public static final int UNIT_X = 0;
    public static final int UNIT_Y = 1;
    // ... etc.

    double convert(double value, int convertTo) {
    // a newUnitConversionFactor to convert
    // from our favorite unit of measurement
    // to our desired unit
        double newUnitConversionFactor = -1;
        switch (convertTo) {
        case UNIT_X:
            newUnitConversionFactor = 1.00;
            break;
        case UNIT_Y:
            newUnitConversionFactor = 1.01;
            break;
        // ... etc.
        }
        return value*conversionFactor*newUnitConversionFactor;
    }
}

然后,您可以通过选择要转换的单位和要转换的单位来简单地转换。例如,如果我想将 UNIT1 的 5.00 转换为 UNITX,我可以简单地使用这个:

UnitOfMeasure.UNIT1.convert(5.00, UnitOfMeasure.UNIT_X);

这样,您还将知道是否调用了转换为您不支持的类型的请求,因为 switch 什么也不做,结果是否定的。

于 2013-08-23T03:47:30.030 回答
0

一般来说,您可以执行以下操作:

//invoking a static method (no instance is required)
public Object invoke(final Class<?> clazz, final String name, final Class<?>[] paramTypes, final Object[] args){
    return invoke(null, name, paramTypes, args);
}

//invoking a method on an object (instance is required)
public Object invoke(final Object instance, final Class<?> clazz, final String name, final Class<?>[] paramTypes, final Object[] args) throws Exception{
    assert clazz != null && name != null : "clazz || method == null";
    assert paramTypes.length == args.length : "paramTypes.length != args.length";
    Method method;
    try{
        //to check if the method has been overridden or not
        method = clazz.getDeclaredMethod(name, paramTypes);
    }catch(NoSuchMethodException | SecurityException ex){
        //if method doesn't exist, exception is thrown
        method = clazz.getMethod(name, paramTypes);
    }
    //if method is protected or private
    if(!method.isAccessible())
        method.setAccessible(true);
    return method.invoke(instance, args);
}

如果您尝试调用的方法没有任何参数,请传入一个空Class<?>[]参数(与参数类似,但空参数除外Object[])。从这个方法返回的对象是刚刚被调用的方法的结果。如果该方法没有返回类型 ( void),则null返回。这个想法是基本上将结果转换为您所期望的任何结果。

于 2013-08-23T03:26:41.400 回答
0

听起来你最好使用带有枚举类型的 switch 块。

您将创建一个像这样的枚举:

public enum Units {
    METERS_TO_FEET("meters", "feet"), FEET_TO_METERS("feet", "meters") /**, etc...*/;

    private final String from;
    private final String to;

    public Units(final String from, final String to) {
        this.from = from;
        this.to = to;
    }

    public static Units fromStrings(String from, String to) {
        if (from != null && to !=null) {
            for (Unit u : Unit.values()) {
                if (from.equalsIgnoreCase(u.from) && to.equalsIgnoreCase(u.to)) {
                    return u;
                }
            }
        }
        return null;
    }
}

并在您的转换方法中使用 switch 块:`

public int convert(String convertFrom, String convertTo, float fromVal, float toVal) {
    Units u = Units.fromStrings(convertFrom, convertTo);
    if(u == null) {
        throw new IllegalArgumentException("Bad input");
    }
    switch(u) {
    case METERS_TO_FEET :
        /** return meters to feet method on fromVal, toVal */
        break;
    case FEET_TO_METERS :
        /** return feet to meters method on fromVal, toVal */
        break;
    /** etc. */
    }
}
于 2013-08-23T03:34:02.653 回答