001/* 002 * Units of Measurement API 003 * Copyright (c) 2014-2023, Jean-Marie Dautelle, Werner Keil, Otavio Santana. 004 * 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without modification, 008 * are permitted provided that the following conditions are met: 009 * 010 * 1. Redistributions of source code must retain the above copyright notice, 011 * this list of conditions and the following disclaimer. 012 * 013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions 014 * and the following disclaimer in the documentation and/or other materials provided with the distribution. 015 * 016 * 3. Neither the name of JSR-385 nor the names of its contributors may be used to endorse or promote products 017 * derived from this software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030// 031// This source code implements specifications defined by the Java 032// Community Process. In order to remain compliant with the specification 033// DO NOT add / change / or delete method signatures! 034// 035package javax.measure; 036 037import java.util.Map; 038 039/** 040 * Represents a determinate {@linkplain Quantity quantity} (as of length, time, heat, or value) adopted as a standard of measurement. 041 * 042 * <p> 043 * It is helpful to think of instances of this class as recording the history by which they are created. Thus, for example, the string {@code "g/kg"} 044 * (which is a dimensionless unit) would result from invoking the method {@link #toString()} on a unit that was created by dividing a gram unit by a 045 * kilogram unit. 046 * </p> 047 * 048 * <p> 049 * This interface supports the multiplication of offsets units. The result is usually a unit not convertible to its {@linkplain #getSystemUnit() 050 * system unit}. Such units may appear in derivative quantities. For example Celsius per meter is an unit of gradient, which is common in atmospheric 051 * and oceanographic research. 052 * </p> 053 * 054 * <p> 055 * Units raised at non-integral powers are not supported. For example, {@code LITRE.root(2)} raises an {@code ArithmeticException}, but 056 * {@code HECTARE.root(2)} returns {@code HECTOMETRE} (100 metres). 057 * </p> 058 * 059 * <p> 060 * Unit instances shall be immutable. 061 * </p> 062 * 063 * @param <Q> 064 * The type of the quantity measured by this unit. 065 * 066 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 067 * @author <a href="mailto:steve@unidata.ucar.edu">Steve Emmerson</a> 068 * @author <a href="mailto:martin.desruisseaux@geomatys.com">Martin Desruisseaux</a> 069 * @author <a href="mailto:werner@units.tech">Werner Keil</a> 070 * @version 2.4, November 11, 2020 071 * @since 1.0 072 * 073 * @see <a href="http://en.wikipedia.org/wiki/Units_of_measurement">Wikipedia: Units of measurement</a> 074 */ 075public interface Unit<Q extends Quantity<Q>> { 076 077 /*******************/ 078 /** Units Queries **/ 079 /*******************/ 080 081 /** 082 * Returns the symbol (if any) of this unit. This method returns {@code null} if this unit has no specific symbol associated with. 083 * 084 * @return this unit symbol, or {@code null} if this unit has not specific symbol associated with (e.g. product of units). 085 * 086 * @see #toString() 087 * @see javax.measure.format.UnitFormat 088 */ 089 String getSymbol(); 090 091 /** 092 * Returns the name (if any) of this unit. This method returns {@code null} if this unit has no specific name associated with. 093 * 094 * @return this unit name, or {@code null} if this unit has not specific name associated with (e.g. product of units). 095 * 096 * @see #toString() 097 * @see javax.measure.format.UnitFormat 098 */ 099 String getName(); 100 101 /** 102 * Returns the dimension of this unit. Two units {@code u1} and {@code u2} are {@linkplain #isCompatible(Unit) compatible} if and only if 103 * {@code u1.getDimension().equals(u2.getDimension())}. 104 * 105 * @return the dimension of this unit. 106 * 107 * @see #isCompatible(Unit) 108 */ 109 Dimension getDimension(); 110 111 /** 112 * Returns the unscaled system unit from which this unit is derived. System units are either base units, {@linkplain #alternate(String) alternate} 113 * units or product of rational powers of system units. 114 * 115 * <p> 116 * Because the system unit is unique by quantity type, it can be be used to identify the quantity given the unit. For example: 117 * </p> 118 * <code> 119 * static boolean isAngularSpeed(Unit<?> unit) {<br> 120 * return unit.getSystemUnit().equals(RADIAN.divide(SECOND));<br> 121 * }<br> 122 * assert isAngularSpeed(REVOLUTION.divide(MINUTE)); // Returns true.<br><br> 123 * </code> 124 * 125 * @return the system unit this unit is derived from, or {@code this} if this unit is a system unit. 126 */ 127 Unit<Q> getSystemUnit(); 128 129 /** 130 * Returns the base units and their exponent whose product is this unit, or {@code null} if this unit is a base unit (not a product of existing 131 * units). 132 * 133 * @return the base units and their exponent making up this unit. 134 */ 135 Map<? extends Unit<?>, Integer> getBaseUnits(); 136 137 /** 138 * Indicates if this unit is compatible with the unit specified. Units don't need to be equal to be compatible. For example (assuming {@code ONE} 139 * is a dimensionless unit):<br> 140 * 141 * <code> 142 * RADIAN.equals(ONE) == false<br> 143 * RADIAN.isCompatible(ONE) == true<br> 144 * RADIAN.isEquivalentTo(ONE) <b>doesn't compile</b><br> 145 * </code> 146 * 147 * @param that 148 * the other unit to compare for compatibility. 149 * @return {@code this.getDimension().equals(that.getDimension())} 150 * 151 * @see #getDimension() 152 */ 153 boolean isCompatible(Unit<?> that); 154 155 /** 156 * Indicates if this unit represents the same quantity than the given unit, ignoring name and symbols. 157 * Two units are equivalent if the {@linkplain #getConverterTo(Unit) conversion} between them is identity. 158 * 159 * <p> 160 * Unlike {@link #isCompatible(Unit)} an equivalence check requires both units to be strictly type-compatible, 161 * because it makes no sense to compare e.g. {@code gram} and {@code mm} for equivalence. 162 * By contrast, the compatibility check can works across different quantity types. 163 * </p> 164 * 165 * @param that the {@code Unit<Q>} to be compared with this instance. 166 * @return {@code true} if {@code that \u2261 this}. 167 * @throws NullPointerException if the unit is null 168 * 169 * @see <a href= "https://dictionary.cambridge.org/dictionary/english/equivalent">Cambridge Dictionary: equivalent</a> 170 * @see <a href= "https://www.lexico.com/en/definition/equivalent">LEXICO: equivalent</a> 171 * @since 2.1 172 */ 173 boolean isEquivalentTo(Unit<Q> that); 174 175 /** 176 * Casts this unit to a parameterized unit of specified nature or throw a {@code ClassCastException} if the dimension of the specified quantity and 177 * this unit's dimension do not match. For example:<br> 178 * 179 * <code> 180 * {@literal Unit<Speed>} C = METRE.multiply(299792458).divide(SECOND).asType(Speed.class); 181 * </code> 182 * 183 * @param <T> 184 * The type of the quantity measured by the unit. 185 * @param type 186 * the quantity class identifying the nature of the unit. 187 * @return this unit parameterized with the specified type. 188 * @throws ClassCastException 189 * if the dimension of this unit is different from the specified quantity dimension. 190 */ 191 <T extends Quantity<T>> Unit<T> asType(Class<T> type) throws ClassCastException; 192 193 /** 194 * Returns a converter of numeric values from this unit to another unit of same type. This method performs the same work as 195 * {@link #getConverterToAny(Unit)} without raising checked exception. 196 * 197 * @param that 198 * the unit of same type to which to convert the numeric values. 199 * @return the converter from this unit to {@code that} unit. 200 * @throws UnconvertibleException 201 * if a converter cannot be constructed. 202 * 203 * @see #getConverterToAny(Unit) 204 */ 205 UnitConverter getConverterTo(Unit<Q> that) throws UnconvertibleException; 206 207 /** 208 * Returns a converter from this unit to the specified unit of type unknown. This method can be used when the quantity type of the specified unit is 209 * unknown at compile-time or when dimensional analysis allows for conversion between units of different type. 210 * 211 * <p> 212 * To convert to a unit having the same parameterized type, {@link #getConverterTo(Unit)} is preferred (no checked exception raised). 213 * </p> 214 * 215 * @param that 216 * the unit to which to convert the numeric values. 217 * @return the converter from this unit to {@code that} unit. 218 * @throws IncommensurableException 219 * if this unit is not {@linkplain #isCompatible(Unit) compatible} with {@code that} unit. 220 * @throws UnconvertibleException 221 * if a converter cannot be constructed. 222 * 223 * @see #getConverterTo(Unit) 224 * @see #isCompatible(Unit) 225 */ 226 UnitConverter getConverterToAny(Unit<?> that) throws IncommensurableException, UnconvertibleException; 227 228 /**********************/ 229 /** Units Operations **/ 230 /**********************/ 231 232 /** 233 * Returns a system unit equivalent to this unscaled standard unit but used in expressions to distinguish between quantities of a different nature 234 * but of the same dimensions. 235 * 236 * <p> 237 * Examples of alternate units: 238 * </p> 239 * 240 * <code> 241 * {@literal Unit<Angle>} RADIAN = ONE.alternate("rad").asType(Angle.class);<br> 242 * {@literal Unit<Force>} NEWTON = METRE.multiply(KILOGRAM).divide(SECOND.pow(2)).alternate("N").asType(Force.class);<br> 243 * {@literal Unit<Pressure>} PASCAL = NEWTON.divide(METRE.pow(2)).alternate("Pa").asType(Pressure.class);<br> 244 * </code> 245 * 246 * @param symbol 247 * the new symbol for the alternate unit. 248 * @return the alternate unit. 249 * @throws IllegalArgumentException 250 * if this unit is not an unscaled standard unit. 251 * @throws MeasurementException 252 * if the specified symbol is not valid or is already associated to a different unit. 253 */ 254 Unit<Q> alternate(String symbol); 255 256 /** 257 * Returns the result of setting the origin of the scale of measurement to the given value. The returned unit is convertible with all units that are 258 * convertible with this unit. For example the following code:<br> 259 * 260 * <code> 261 * CELSIUS = KELVIN.shift(273.15); 262 * </code> 263 * 264 * creates a new unit where 0°C (the origin of the new unit) is equals to 273.15 K. Converting from the old unit to the new one is equivalent to 265 * <em>subtracting</em> the offset to the value in the old unit. 266 * 267 * @param offset 268 * the offset added (expressed in this unit). 269 * @return this unit offset by the specified value. 270 * @since 2.0 271 */ 272 Unit<Q> shift(Number offset); 273 274 /** 275 * Returns the result of setting the origin of the scale of measurement to the given value. The returned unit is convertible with all units that are 276 * convertible with this unit. For example the following code:<br> 277 * 278 * <code> 279 * CELSIUS = KELVIN.shift(273.15); 280 * </code> 281 * 282 * creates a new unit where 0°C (the origin of the new unit) is equals to 273.15 K. Converting from the old unit to the new one is equivalent to 283 * <em>subtracting</em> the offset to the value in the old unit. 284 * 285 * @param offset 286 * the offset added (expressed in this unit). 287 * @return this unit offset by the specified value. 288 */ 289 Unit<Q> shift(double offset); 290 291 /** 292 * Returns the result of multiplying this unit by the specified factor. If the factor is an integer value, the multiplication is exact 293 * (recommended). For example:<br> 294 * 295 * <code> 296 * FOOT = METRE.multiply(3048).divide(10000); // Exact definition.<br> 297 * ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31); // Approximation. 298 * </code> 299 * 300 * @param multiplier 301 * the multiplier 302 * @return this unit scaled by the specified multiplier. 303 * @since 2.0 304 */ 305 Unit<Q> multiply(Number multiplier); 306 307 /** 308 * Returns the result of multiplying this unit by the specified factor. For example:<br> 309 * 310 * <code> 311 * FOOT = METRE.multiply(3048).divide(10000); // Exact definition.<br> 312 * ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31); // Approximation. 313 * </code> 314 * 315 * @param multiplier 316 * the multiplier 317 * @return this unit scaled by the specified multiplier. 318 */ 319 Unit<Q> multiply(double multiplier); 320 321 /** 322 * Returns the product of this unit with the one specified. 323 * 324 * @param multiplier 325 * the unit multiplier. 326 * @return {@code this * multiplier} 327 */ 328 Unit<?> multiply(Unit<?> multiplier); 329 330 /** 331 * Returns the reciprocal (multiplicative inverse) of this unit. 332 * 333 * @return {@code 1 / this} 334 * @see <a href="https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia: Multiplicative inverse</a> 335 */ 336 Unit<?> inverse(); 337 338 /** 339 * Returns the result of dividing this unit by a divisor. If the factor is an integer value, the division is exact. For example:<br> 340 * 341 * <code> 342 * GRAM = KILOGRAM.divide(1000); // Exact definition. 343 * </code> 344 * 345 * @param divisor 346 * the divisor value. 347 * @return this unit divided by the specified divisor. 348 * @since 2.0 349 */ 350 Unit<Q> divide(Number divisor); 351 352 /** 353 * Returns the result of dividing this unit by an approximate divisor. For example:<br> 354 * 355 * <code> 356 * GRAM = KILOGRAM.divide(1000d); 357 * </code> 358 * 359 * @param divisor 360 * the divisor value. 361 * @return this unit divided by the specified divisor. 362 */ 363 Unit<Q> divide(double divisor); 364 365 /** 366 * Returns the quotient of this unit with the one specified. 367 * 368 * @param divisor 369 * the unit divisor. 370 * @return {@code this / divisor} 371 */ 372 Unit<?> divide(Unit<?> divisor); 373 374 /** 375 * Returns an unit that is the n-th (integer) root of this unit. Equivalent to the mathematical expression {@code unit^(1/n)}. 376 * 377 * @param n 378 * an integer giving the root's order as in 'n-th root' 379 * @return the n-th root of this unit. 380 * @throws ArithmeticException 381 * if {@code n == 0} or if this operation would result in an unit with a fractional exponent. 382 */ 383 Unit<?> root(int n); 384 385 /** 386 * Returns an unit raised to the n-th (integer) power of this unit. Equivalent to the mathematical expression {@code unit^n}. 387 * 388 * @param n 389 * the exponent. 390 * @return the result of raising this unit to the exponent. 391 */ 392 Unit<?> pow(int n); 393 394 /** 395 * Returns the unit derived from this unit using the specified converter. The converter does not need to be linear. For example:<br> 396 * 397 * <pre> 398 * {@literal Unit<Dimensionless>} DECIBEL = Unit.ONE.transform( 399 * new LogConverter(10).inverse().concatenate( 400 * new RationalConverter(1, 10))); 401 * </pre> 402 * 403 * @param operation 404 * the converter from the transformed unit to this unit. 405 * @return the unit after the specified transformation. 406 */ 407 Unit<Q> transform(UnitConverter operation); 408 409 /** 410 * Returns a string representation of this unit. The string representation may be the unit {@linkplain #getSymbol() symbol}, or may be some 411 * representation of {@linkplain #getBaseUnits() product units}, multiplication factor and offset if any. 412 * 413 * <p> 414 * The string may be localized at implementation choice by the means of a particular device and platform. 415 * </p> 416 * 417 * @return the string representation of this unit. 418 * 419 * @see #getSymbol() 420 * @see javax.measure.format.UnitFormat 421 */ 422 @Override 423 String toString(); 424 425 /** 426 * Returns a new unit equal to this unit prefixed by the specified {@code prefix}. 427 * 428 * @param prefix 429 * the prefix to apply on this unit. 430 * @return the unit with the given prefix applied. 431 * @since 2.0 432 */ 433 Unit<Q> prefix(Prefix prefix); 434}