【问题标题】:Converting different unit types in JScience library在 JScience 库中转换不同的单位类型
【发布时间】:2023-03-15 21:36:01
【问题描述】:

我正在 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);
}

【问题讨论】:

    标签: java jscience


    【解决方案1】:

    看起来JScience 发现您试图将Unit&lt;Mass&gt; 转换为Unit&lt;Energy&gt;,这在默认PhysicalModel 中是被禁止的。

    另一种方法是为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

    【讨论】:

      猜你喜欢
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 2015-07-18
      • 2015-06-23
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2011-04-17
      相关资源
      最近更新 更多