My personal take on a units of measurement library for java.
The design goal of the library is to include:
- fully typed quantities:
Length l1 = Length.of(1, SI.METRE); Length l2 = Length.ofMeter(2); // convenience factory method for SI unit
- transparent support for double and arbitrary decimal precision quantities (using BigDecimal):
Length l1 = Quantities.create(1, SI.METRE); Length l2 = Quantities.create(BigDecimal.ONE, Intl.YARD); Length l3 = l1.add(l2); // quantities with different precision can be used together
- support for generic quantities:
Quantity<Speed> speed = Quantities.createGeneric(1, SI.METER_PER_SECOND); System.out.println(speed.add(Speed.ofMeterPerSecond(2))); // -> prints 3 m/s
- support for quantity factories:
QuantityFactory<Length> factory = DoubleQuantity.factory(Length.class); Length l1 = factory.create(1, SI.METRE); // default factories can be replaced // use decimal precision with MathContext DECIMAL128 for every quantity of type Length: Quantities.registerQuantityFactory(Length.class, DecimalQuantity.factory(MathContext.DECIMAL128, Length.class)); // quantity factories with pooling behavior can be registered QuantityFactory<Length> myPoolFactory = ...; Quantities.registerQuantityFactory(Length.class, myPoolFactory);
- support for the standard unit manipulations as defined by JSR-385 et al
- support for as many units as possible, the amazing GNU units library is the reference to compare to
The library uses dynamic proxies to create concrete quantity classes for the specified precision at runtime.
Conversion of units between different system of units, e.g. SI and CGS
ElectricCharge e1 = ElectricCharge.of(1, SI.COULOMB);
ElectricCharge e2 = e1.to(ESU.STATCOULOMB);
System.out.println(e2);
prints
2.997925e+09 statC
Custom quantities and units:
public interface Bmi extends Quantity<Bmi> {}
...
final Unit<Bmi> bmiUnit = SI.KILOGRAM.divide(SI.METRE.pow(2)).withSymbol("B").forQuantity(Bmi.class);
Quantity<Bmi> bmiDouble = Quantities.createGeneric(19, bmiUnit);
Quantity<Bmi> bmiDecimal = Quantities.createGeneric(BigDecimal.valueOf(21), bmiUnit);
System.out.println(bmiDouble);
Code is under the Apache Licence v2.