001/* 002 * Units of Measurement API 003 * Copyright (c) 2014-2019, 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:[email protected]">Jean-Marie Dautelle</a> 067 * @author <a href="mailto:[email protected]">Steve Emmerson</a> 068 * @author <a href="mailto:[email protected]">Martin Desruisseaux</a> 069 * @author <a href="mailto:[email protected]">Werner Keil</a> 070 * @version 2.1, May 12, 2019 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 equals 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 * </code> 145 * 146 * @param that 147 * the other unit to compare for compatibility. 148 * @return {@code this.getDimension().equals(that.getDimension())} 149 * 150 * @see #getDimension() 151 */ 152 boolean isCompatible(Unit<?> that); 153 154 /** 155 * Casts this unit to a parameterized unit of specified nature or throw a {@code ClassCastException} if the dimension of the specified quantity and 156 * this unit's dimension do not match. For example:<br> 157 * 158 * <code> 159 * {@literal Unit<Speed>} C = METRE.multiply(299792458).divide(SECOND).asType(Speed.class); 160 * </code> 161 * 162 * @param <T> 163 * The type of the quantity measured by the unit. 164 * @param type 165 * the quantity class identifying the nature of the unit. 166 * @return this unit parameterized with the specified type. 167 * @throws ClassCastException 168 * if the dimension of this unit is different from the specified quantity dimension. 169 */ 170 <T extends Quantity<T>> Unit<T> asType(Class<T> type) throws ClassCastException; 171 172 /** 173 * Returns a converter of numeric values from this unit to another unit of same type. This method performs the same work as 174 * {@link #getConverterToAny(Unit)} without raising checked exception. 175 * 176 * @param that 177 * the unit of same type to which to convert the numeric values. 178 * @return the converter from this unit to {@code that} unit. 179 * @throws UnconvertibleException 180 * if a converter cannot be constructed. 181 * 182 * @see #getConverterToAny(Unit) 183 */ 184 UnitConverter getConverterTo(Unit<Q> that) throws UnconvertibleException; 185 186 /** 187 * 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 188 * unknown at compile-time or when dimensional analysis allows for conversion between units of different type. 189 * 190 * <p> 191 * To convert to a unit having the same parameterized type, {@link #getConverterTo(Unit)} is preferred (no checked exception raised). 192 * </p> 193 * 194 * @param that 195 * the unit to which to convert the numeric values. 196 * @return the converter from this unit to {@code that} unit. 197 * @throws IncommensurableException 198 * if this unit is not {@linkplain #isCompatible(Unit) compatible} with {@code that} unit. 199 * @throws UnconvertibleException 200 * if a converter cannot be constructed. 201 * 202 * @see #getConverterTo(Unit) 203 * @see #isCompatible(Unit) 204 */ 205 UnitConverter getConverterToAny(Unit<?> that) throws IncommensurableException, UnconvertibleException; 206 207 /**********************/ 208 /** Units Operations **/ 209 /**********************/ 210 211 /** 212 * Returns a system unit equivalent to this unscaled standard unit but used in expressions to distinguish between quantities of a different nature 213 * but of the same dimensions. 214 * 215 * <p> 216 * Examples of alternate units: 217 * </p> 218 * 219 * <code> 220 * {@literal Unit<Angle>} RADIAN = ONE.alternate("rad").asType(Angle.class);<br> 221 * {@literal Unit<Force>} NEWTON = METRE.multiply(KILOGRAM).divide(SECOND.pow(2)).alternate("N").asType(Force.class);<br> 222 * {@literal Unit<Pressure>} PASCAL = NEWTON.divide(METRE.pow(2)).alternate("Pa").asType(Pressure.class);<br> 223 * </code> 224 * 225 * @param symbol 226 * the new symbol for the alternate unit. 227 * @return the alternate unit. 228 * @throws IllegalArgumentException 229 * if this unit is not an unscaled standard unit. 230 * @throws MeasurementException 231 * if the specified symbol is not valid or is already associated to a different unit. 232 */ 233 Unit<Q> alternate(String symbol); 234 235 /** 236 * 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 237 * convertible with this unit. For example the following code:<br> 238 * 239 * <code> 240 * CELSIUS = KELVIN.shift(273.15); 241 * </code> 242 * 243 * 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 244 * <em>subtracting</em> the offset to the value in the old unit. 245 * 246 * @param offset 247 * the offset added (expressed in this unit). 248 * @return this unit offset by the specified value. 249 * @since 2.0 250 */ 251 Unit<Q> shift(Number offset); 252 253 /** 254 * 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 255 * convertible with this unit. For example the following code:<br> 256 * 257 * <code> 258 * CELSIUS = KELVIN.shift(273.15); 259 * </code> 260 * 261 * 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 262 * <em>subtracting</em> the offset to the value in the old unit. 263 * 264 * @param offset 265 * the offset added (expressed in this unit). 266 * @return this unit offset by the specified value. 267 */ 268 Unit<Q> shift(double offset); 269 270 /** 271 * Returns the result of multiplying this unit by the specified factor. If the factor is an integer value, the multiplication is exact 272 * (recommended). For example:<br> 273 * 274 * <code> 275 * FOOT = METRE.multiply(3048).divide(10000); // Exact definition.<br> 276 * ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31); // Approximation. 277 * </code> 278 * 279 * @param multiplier 280 * the multiplier 281 * @return this unit scaled by the specified multiplier. 282 * @since 2.0 283 */ 284 Unit<Q> multiply(Number multiplier); 285 286 /** 287 * Returns the result of multiplying this unit by the specified factor. For example:<br> 288 * 289 * <code> 290 * FOOT = METRE.multiply(3048).divide(10000); // Exact definition.<br> 291 * ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31); // Approximation. 292 * </code> 293 * 294 * @param multiplier 295 * the multiplier 296 * @return this unit scaled by the specified multiplier. 297 */ 298 Unit<Q> multiply(double multiplier); 299 300 /** 301 * Returns the product of this unit with the one specified. 302 * 303 * @param multiplier 304 * the unit multiplier. 305 * @return {@code this * multiplier} 306 */ 307 Unit<?> multiply(Unit<?> multiplier); 308 309 /** 310 * Returns the reciprocal (multiplicative inverse) of this unit. 311 * 312 * @return {@code 1 / this} 313 * @see <a href="https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia: Multiplicative inverse</a> 314 */ 315 Unit<?> inverse(); 316 317 /** 318 * Returns the result of dividing this unit by a divisor. If the factor is an integer value, the division is exact. For example:<br> 319 * 320 * <code> 321 * GRAM = KILOGRAM.divide(1000); // Exact definition. 322 * </code> 323 * 324 * @param divisor 325 * the divisor value. 326 * @return this unit divided by the specified divisor. 327 * @since 2.0 328 */ 329 Unit<Q> divide(Number divisor); 330 331 /** 332 * Returns the result of dividing this unit by an approximate divisor. For example:<br> 333 * 334 * <code> 335 * GRAM = KILOGRAM.divide(1000d); 336 * </code> 337 * 338 * @param divisor 339 * the divisor value. 340 * @return this unit divided by the specified divisor. 341 */ 342 Unit<Q> divide(double divisor); 343 344 /** 345 * Returns the quotient of this unit with the one specified. 346 * 347 * @param divisor 348 * the unit divisor. 349 * @return {@code this / divisor} 350 */ 351 Unit<?> divide(Unit<?> divisor); 352 353 /** 354 * Returns an unit that is the n-th (integer) root of this unit. Equivalent to the mathematical expression {@code unit^(1/n)}. 355 * 356 * @param n 357 * an integer giving the root's order as in 'n-th root' 358 * @return the n-th root of this unit. 359 * @throws ArithmeticException 360 * if {@code n == 0} or if this operation would result in an unit with a fractional exponent. 361 */ 362 Unit<?> root(int n); 363 364 /** 365 * Returns an unit raised to the n-th (integer) power of this unit. Equivalent to the mathematical expression {@code unit^n}. 366 * 367 * @param n 368 * the exponent. 369 * @return the result of raising this unit to the exponent. 370 */ 371 Unit<?> pow(int n); 372 373 /** 374 * Returns the unit derived from this unit using the specified converter. The converter does not need to be linear. For example:<br> 375 * 376 * <pre> 377 * {@literal Unit<Dimensionless>} DECIBEL = Unit.ONE.transform( 378 * new LogConverter(10).inverse().concatenate( 379 * new RationalConverter(1, 10))); 380 * </pre> 381 * 382 * @param operation 383 * the converter from the transformed unit to this unit. 384 * @return the unit after the specified transformation. 385 */ 386 Unit<Q> transform(UnitConverter operation); 387 388 /** 389 * Returns a string representation of this unit. The string representation may be the unit {@linkplain #getSymbol() symbol}, or may be some 390 * representation of {@linkplain #getBaseUnits() product units}, multiplication factor and offset if any. 391 * 392 * <p> 393 * The string may be localized at implementation choice by the means of a particular device and platform. 394 * </p> 395 * 396 * @return the string representation of this unit. 397 * 398 * @see #getSymbol() 399 * @see javax.measure.format.UnitFormat 400 */ 401 @Override 402 String toString(); 403 404 /** 405 * Returns a new unit equal to this unit prefixed by the specified {@code prefix}. 406 * 407 * @param prefix 408 * the prefix to apply on this unit. 409 * @return the unit with the given prefix applied. 410 * @since 2.0 411 */ 412 Unit<Q> prefix(Prefix prefix); 413}