在JScience库中转换不同的单位类型 [英] Converting different unit types in JScience library

查看:312
本文介绍了在JScience库中转换不同的单位类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在JScience库中寻找一种将一种单位类型转换为另一种单位类型的方法.给定每种类型的基本单位之间的因子,我应该可以转换.但是,似乎JScience对转换不是很好,只允许在相同基本类型的单元之间进行转换.

基本上,我正在编写一个减肥应用程序,我需要能够在卡路里,焦耳,千焦耳,克,磅,千克等之间进行转换.它的大量营养成分(碳水化合物,碳水化合物,蛋白质和脂肪)非常复杂内容.

示例:

每1克碳水化合物= 4卡路里.那是4000卡路里,或16.736千焦耳,或16736焦耳(能量的基本单位).

Carb_Unit然后定义为:16736焦耳/克,或16736000焦耳/千克

鉴于此基本值,我应该能够从任何质量单位转换为任何能量单位.但是同样,JScience不允许这样做.有没有办法告诉转换器返回具有正确转换因子的转换器,而又不给出ConversionException?

CustomUnits.java:

public class CustomUnits extends SystemOfUnits {

    /**
     * Holds collection of CustomUnits.
     */
    private static HashSet<Unit<?>> UNITS = new HashSet<Unit<?>>();

    private static <U extends Unit<?>> U customUnits(U unit) {
        UNITS.add(unit);
        return unit;
    }

    @Override
    public Set<Unit<?>> getUnits() {
        return Collections.unmodifiableSet(UNITS);
    }

    public static final Unit<Energy> KILOCALORIE = customUnits(SI.JOULE.times(4184));
    public static final Unit<Energy> KILOJOULE = customUnits(SI.JOULE.times(1000));

    // Food units expressed as energy
    public static final Unit<Energy> CARBOHYDRATE_ENERGY = customUnits(KILOCALORIE.times(4));
    public static final Unit<Energy> PROTEIN_ENERGY = customUnits(KILOCALORIE.times(4));
    public static final Unit<Energy> FAT_ENERGY = customUnits(KILOCALORIE.times(9));

    // Food units expressed as mass
    public static final Unit<Mass> CARBOHYDRATE_MASS = customUnits(SI.GRAM);
    public static final Unit<Mass> PROTEIN_MASS = customUnits(SI.GRAM);
    public static final Unit<Mass> FAT_MASS = customUnits(SI.GRAM);
}

Main.java:

public static void main(String[] args) {

    Amount<?> carbEnergyUnit = Amount.valueOf(1, CustomUnits.CARBOHYDRATE_ENERGY);
    Amount<?> carbEnergyCalorie = carbEnergyUnit.to(CustomUnits.KILOCALORIE);
    Amount<?> carbEnergyKJ = carbEnergyUnit.to(CustomUnits.KILOJOULE);
    Amount<?> carbEnergyJoules = carbEnergyUnit.to(SI.JOULE);

    System.out.println(carbEnergyUnit.getExactValue() + "g of carb");       // 1g of carb
    System.out.println(carbEnergyCalorie.getExactValue() + " Calorie");     // 4 Calorie
    System.out.println(carbEnergyKJ.getEstimatedValue() + " KiloJoules");   // 16.735999999999997 KiloJoules
    System.out.println(carbEnergyJoules.getExactValue() + " Joules");       // 16736 Joules

    // Exception in thread "main" javax.measure.converter.ConversionException: lb is not compatible with J*16736
    UnitConverter toCarb = NonSI.POUND.getConverterTo(CustomUnits.CARBOHYDRATE_ENERGY);
    double result = toCarb.convert(4);
    System.out.println(result);
}

解决方案

看来JScience抓住了您尝试将Unit<Mass>转换为Unit<Energy>的情况,这在默认的PhysicalModel中是禁止的./p>

一种替代方法是为FoodEnergy的各种单位创建一个新的Quantity:

public static final Unit<Energy> KILOCALORIE = SI.JOULE.times(4184);

public interface FoodEnergy extends Quantity {

    public final static Unit<FoodEnergy> UNIT
        = (Unit<FoodEnergy>) SI.GRAM.times(KILOCALORIE);
}

private static final Unit<FoodEnergy> PROTEIN_ENERGY = FoodEnergy.UNIT.times(4);
private static final Unit<FoodEnergy> ETHANOL_ENERGY = FoodEnergy.UNIT.times(7);
…

然后您可以合并特定能源的贡献:

Amount<FoodEnergy> beer =
    Amount.valueOf(2, PROTEIN_ENERGY).plus(
    Amount.valueOf(14, ETHANOL_ENERGY));
System.out.println(beer.to(FoodEnergy.UNIT).getEstimatedValue() + " Calories");

哪个打印105.99999999999997 Calories.您可以通过将NonSI.POUND转换为SI.GRAM来找到一磅蛋白质中的卡路里:

double grams = NonSI.POUND.getConverterTo(SI.GRAM).convert(1);
Amount<FoodEnergy> pound = Amount.valueOf(grams, PROTEIN_ENERGY);
System.out.println(pound.to(FoodEnergy.UNIT).getEstimatedValue() + " Calories");

哪个打印1814.3694799999998 Calories.最后,您可以从FoodEnergy.UNIT中恢复焦耳数:

System.out.println(FoodEnergy.UNIT.divide(SI.GRAM));

打印J*4184

System.out.println(FoodEnergy.UNIT.divide(SI.GRAM).toStandardUnit().convert(1));

哪个打印4184.0.

I'm looking for a way in the JScience library to convert from one unit type to another. Given a factor between the base units of each types I should be able to convert. But it seems that JScience isn't being very nice about the conversion, and only allowing the conversion between units of the same base type.

Basically, I'm writing a diet app, and I need to be able to convert between calories, joules, kilojoules, grams, pounds, kg, etc. It is complicated by the macronutrient values - carbohyrates, protein, and fat content.

Example:

Each 1g of carb = 4 Calorie. That's 4000 calorie, or 16.736 Kilojoules, or 16736 joules (the base unit of energy).

Carb_Unit is then defined as: 16736 joules/gram, or 16736000joules/kilogram

Given this base values, I should be able to convert from any mass unit to any energy unit. But again, JScience won't allow this. Is there a way to tell the converter to return a converter with the correct conversion factor without it giving out the ConversionException?

CustomUnits.java:

public class CustomUnits extends SystemOfUnits {

    /**
     * Holds collection of CustomUnits.
     */
    private static HashSet<Unit<?>> UNITS = new HashSet<Unit<?>>();

    private static <U extends Unit<?>> U customUnits(U unit) {
        UNITS.add(unit);
        return unit;
    }

    @Override
    public Set<Unit<?>> getUnits() {
        return Collections.unmodifiableSet(UNITS);
    }

    public static final Unit<Energy> KILOCALORIE = customUnits(SI.JOULE.times(4184));
    public static final Unit<Energy> KILOJOULE = customUnits(SI.JOULE.times(1000));

    // Food units expressed as energy
    public static final Unit<Energy> CARBOHYDRATE_ENERGY = customUnits(KILOCALORIE.times(4));
    public static final Unit<Energy> PROTEIN_ENERGY = customUnits(KILOCALORIE.times(4));
    public static final Unit<Energy> FAT_ENERGY = customUnits(KILOCALORIE.times(9));

    // Food units expressed as mass
    public static final Unit<Mass> CARBOHYDRATE_MASS = customUnits(SI.GRAM);
    public static final Unit<Mass> PROTEIN_MASS = customUnits(SI.GRAM);
    public static final Unit<Mass> FAT_MASS = customUnits(SI.GRAM);
}

Main.java:

public static void main(String[] args) {

    Amount<?> carbEnergyUnit = Amount.valueOf(1, CustomUnits.CARBOHYDRATE_ENERGY);
    Amount<?> carbEnergyCalorie = carbEnergyUnit.to(CustomUnits.KILOCALORIE);
    Amount<?> carbEnergyKJ = carbEnergyUnit.to(CustomUnits.KILOJOULE);
    Amount<?> carbEnergyJoules = carbEnergyUnit.to(SI.JOULE);

    System.out.println(carbEnergyUnit.getExactValue() + "g of carb");       // 1g of carb
    System.out.println(carbEnergyCalorie.getExactValue() + " Calorie");     // 4 Calorie
    System.out.println(carbEnergyKJ.getEstimatedValue() + " KiloJoules");   // 16.735999999999997 KiloJoules
    System.out.println(carbEnergyJoules.getExactValue() + " Joules");       // 16736 Joules

    // Exception in thread "main" javax.measure.converter.ConversionException: lb is not compatible with J*16736
    UnitConverter toCarb = NonSI.POUND.getConverterTo(CustomUnits.CARBOHYDRATE_ENERGY);
    double result = toCarb.convert(4);
    System.out.println(result);
}

解决方案

It looks like JScience has caught you trying to convert a Unit<Mass> to a Unit<Energy>, which is forbidden in the default PhysicalModel.

One alternative approach would be to create a new Quantity for various units of FoodEnergy:

public static final Unit<Energy> KILOCALORIE = SI.JOULE.times(4184);

public interface FoodEnergy extends Quantity {

    public final static Unit<FoodEnergy> UNIT
        = (Unit<FoodEnergy>) SI.GRAM.times(KILOCALORIE);
}

private static final Unit<FoodEnergy> PROTEIN_ENERGY = FoodEnergy.UNIT.times(4);
private static final Unit<FoodEnergy> ETHANOL_ENERGY = FoodEnergy.UNIT.times(7);
…

You can then combine the contributions of particular energy sources:

Amount<FoodEnergy> beer =
    Amount.valueOf(2, PROTEIN_ENERGY).plus(
    Amount.valueOf(14, ETHANOL_ENERGY));
System.out.println(beer.to(FoodEnergy.UNIT).getEstimatedValue() + " Calories");

Which prints 105.99999999999997 Calories. You can find the calories in a pound of protein by converting a NonSI.POUND to SI.GRAM:

double grams = NonSI.POUND.getConverterTo(SI.GRAM).convert(1);
Amount<FoodEnergy> pound = Amount.valueOf(grams, PROTEIN_ENERGY);
System.out.println(pound.to(FoodEnergy.UNIT).getEstimatedValue() + " Calories");

Which prints 1814.3694799999998 Calories. Finally, you can recover the number of Joules from a FoodEnergy.UNIT:

System.out.println(FoodEnergy.UNIT.divide(SI.GRAM));

Which prints J*4184, or

System.out.println(FoodEnergy.UNIT.divide(SI.GRAM).toStandardUnit().convert(1));

Which prints 4184.0.

这篇关于在JScience库中转换不同的单位类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆