001/* 002 * Units of Measurement API 003 * Copyright (c) 2014-2015, Jean-Marie Dautelle, Werner Keil, V2COM. 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-363 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 041 * length, time, heat, or value) adopted as a standard of measurement. 042 * 043 * <p>It is helpful to think of instances of this class as recording the history 044 * by which they are created. Thus, for example, the string {@code "g/kg"} (which 045 * is a dimensionless unit) would result from invoking the method {@link #toString()} 046 * on a unit that was created by dividing a gram unit by a kilogram unit.</p> 047 * 048 * <p>This interface supports the multiplication of offsets units. The result is 049 * usually a unit not convertible to its {@linkplain #getSystemUnit() system unit}. 050 * Such units may appear in derivative quantities. For example Celsius per meter is 051 * an unit of gradient, which is common in atmospheric and oceanographic research.</p> 052 * 053 * <p>Units raised at non-integral powers are not supported. For example, 054 * {@code LITRE.root(2)} raises an {@code ArithmeticException}, but 055 * {@code HECTARE.root(2)} returns {@code HECTOMETRE} (100 metres).</p> 056 * 057 * <p>Unit instances shall be immutable.</p> 058 * 059 * @param <Q> The type of the quantity measured by this unit. 060 * 061 * @author <a href="mailto:[email protected]">Jean-Marie Dautelle</a> 062 * @author <a href="mailto:[email protected]">Steve Emmerson</a> 063 * @author <a href="mailto:[email protected]">Martin Desruisseaux</a> 064 * @author <a href="mailto:[email protected]">Werner Keil</a> 065 * @version 0.19, October 13, 2015 066 * 067 * @see <a href="http://en.wikipedia.org/wiki/Units_of_measurement">Wikipedia: Units of measurement</a> 068 */ 069public interface Unit<Q extends Quantity<Q>> { 070 071 /*******************/ 072 /** Units Queries **/ 073 /*******************/ 074 075 /** 076 * Returns the symbol (if any) of this unit. 077 * This method returns {@code null} if this unit has no specific symbol associated with. 078 * 079 * @return this unit symbol, or {@code null} if this unit has not 080 * specific symbol associated with (e.g. product of units). 081 * 082 * @see #toString() 083 * @see UnitFormat 084 */ 085 String getSymbol(); 086 087 /** 088 * Returns the name (if any) of this unit. 089 * This method returns {@code null} if this unit has no specific name associated with. 090 * 091 * @return this unit name, or {@code null} if this unit has not 092 * specific name associated with (e.g. product of units). 093 * 094 * @see #toString() 095 * @see UnitFormat 096 */ 097 String getName(); 098 099 /** 100 * Returns the dimension of this unit. Two units {@code u1} and {@code u2} 101 * are {@linkplain #isCompatible(Unit) compatible} if and only if 102 * {@code u1.getDimension().equals(u2.getDimension())}. 103 * 104 * @return the dimension of this unit. 105 * 106 * @see #isCompatible(Unit) 107 */ 108 Dimension getDimension(); 109 110 /** 111 * Returns the unscaled system unit from which this unit is derived. 112 * System units are either base units, {@linkplain #alternate(String) 113 * alternate} units or product of rational powers of system units. 114 * 115 * <p>Because the system unit is unique by quantity type, it can be 116 * be used to identify the quantity given the unit. For example:</p> 117 * 118 * [code] 119 * static boolean isAngularSpeed(Unit<?> unit) { 120 * return unit.getSystemUnit().equals(RADIAN.divide(SECOND)); 121 * } 122 * assert isAngularSpeed(REVOLUTION.divide(MINUTE)); // Returns true. 123 * [/code] 124 * 125 * @return the system unit this unit is derived from, 126 * or {@code this} if this unit is a system unit. 127 */ 128 Unit<Q> getSystemUnit(); 129 130 /** 131 * Returns the base units and their exponent whose product is this unit, 132 * or {@code null} if this unit is a base unit (not a product of existing units). 133 * 134 * @return the base units and their exponent making up this unit. 135 */ 136 Map<? extends Unit<?>, Integer> getProductUnits(); 137 138 /** 139 * Indicates if this unit is compatible with the unit specified. 140 * Units don't need to be equals to be compatible. For example 141 * (assuming {@code ONE} is a dimensionless unit): 142 * 143 * [code] 144 * RADIAN.equals(ONE) == false 145 * RADIAN.isCompatible(ONE) == true 146 * [/code] 147 * 148 * @param that 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 * Casts this unit to a parameterized unit of specified nature or throw a 157 * {@code ClassCastException} if the dimension of the specified quantity 158 * and this unit's dimension do not match. For example: 159 * 160 * [code] 161 * Unit<Speed> C = METRE.times(299792458).divide(SECOND).asType(Speed.class); 162 * [/code] 163 * 164 * @param <T> The type of the quantity measured by the unit. 165 * @param type the quantity class identifying the nature of the unit. 166 * @return this unit parameterized with the specified type. 167 * @throws ClassCastException if the dimension of this unit is different 168 * 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. 174 * This method performs the same work than {@link #getConverterToAny(Unit)} without 175 * raising checked exception. 176 * 177 * @param that 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 if a converter cannot be constructed. 180 * 181 * @see #getConverterToAny(Unit) 182 */ 183 UnitConverter getConverterTo(Unit<Q> that) throws UnconvertibleException; 184 185 /** 186 * Returns a converter from this unit to the specified unit of type unknown. 187 * This method can be used when the quantity type of the specified unit 188 * is unknown at compile-time or when dimensional analysis allows for 189 * conversion between units of different type. 190 * 191 * <p>To convert to a unit having the same parameterized type, 192 * {@link #getConverterTo(Unit)} is preferred (no checked exception raised).</p> 193 * 194 * @param that the unit to which to convert the numeric values. 195 * @return the converter from this unit to {@code that} unit. 196 * @throws IncommensurableException if this unit is not 197 * {@linkplain #isCompatible(Unit) compatible} with {@code that}�unit. 198 * @throws UnconvertibleException if a converter cannot be constructed. 199 * 200 * @see #getConverterTo(Unit) 201 * @see #isCompatible(Unit) 202 */ 203 UnitConverter getConverterToAny(Unit<?> that) throws IncommensurableException, 204 UnconvertibleException; 205 206 /**********************/ 207 /** Units Operations **/ 208 /**********************/ 209 210 /** 211 * Returns a system unit equivalent to this unscaled standard unit but used 212 * in expressions to distinguish between quantities of a different nature 213 * but of the same dimensions. 214 * 215 * <p>Examples of alternate units:</p> 216 * 217 * [code] 218 * Unit<Angle> RADIAN = ONE.alternate("rad").asType(Angle.class); 219 * Unit<Force> NEWTON = METRE.times(KILOGRAM).divide(SECOND.pow(2)).alternate("N").asType(Force.class); 220 * Unit<Pressure> PASCAL = NEWTON.divide(METRE.pow(2)).alternate("Pa").asType(Pressure.class); 221 * [/code] 222 * 223 * @param symbol the new symbol for the alternate unit. 224 * @return the alternate unit. 225 * @throws UnsupportedOperationException if this unit is not an unscaled standard unit. 226 * @throws IllegalArgumentException if the specified symbol is already 227 * associated to a different unit. 228 */ 229 Unit<Q> alternate(String symbol); 230 231 /** 232 * Returns the result of setting the origin of the scale of measurement to the given value. 233 * The returned unit is convertible with all units that are convertible with this unit. 234 * For example the following code: 235 * 236 * <code> 237 * CELSIUS = KELVIN.shift(273.15); 238 * </code> 239 * 240 * creates a new unit where 0�C (the origin of the new unit) is equals to 273.15 K. 241 * Converting from the old unit to the new one is equivalent to <em>subtracting</em> 242 * the offset to the value in the old unit. 243 * 244 * @param offset the offset added (expressed in this unit). 245 * @return this unit offset by the specified value. 246 */ 247 Unit<Q> shift(double offset); 248 249 /** 250 * Returns the result of multiplying this unit by the specified factor. 251 * If the factor is an integer value, the multiplication is exact 252 * (recommended). For example: 253 * 254 * <code> 255 * FOOT = METRE.multiply(3048).divide(10000); // Exact definition. 256 * ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31); // Approximation. 257 * </code> 258 * 259 * @param multiplier the multiplier 260 * @return this unit scaled by the specified multiplier. 261 */ 262 Unit<Q> multiply(double multiplier); 263 264 /** 265 * Returns the product of this unit with the one specified. 266 * 267 * @param multiplier the unit multiplier. 268 * @return {@code this * multiplier} 269 */ 270 Unit<?> multiply(Unit<?> multiplier); 271 272 /** 273 * Returns the inverse of this unit. 274 * 275 * @return {@code 1 / this} 276 */ 277 Unit<?> inverse(); 278 279 /** 280 * Returns the result of dividing this unit by an approximate divisor. 281 * If the factor is an integer value, the division is exact. 282 * For example: 283 * 284 * <code> 285 * GRAM = KILOGRAM.divide(1000); // Exact definition. 286 * </code> 287 * 288 * @param divisor the divisor value. 289 * @return this unit divided by the specified divisor. 290 */ 291 Unit<Q> divide(double divisor); 292 293 /** 294 * Returns the quotient of this unit with the one specified. 295 * 296 * @param divisor the unit divisor. 297 * @return {@code this / divisor} 298 */ 299 Unit<?> divide(Unit<?> divisor); 300 301 /** 302 * Returns a unit equals to the given root of this unit. 303 * 304 * @param n the root's order. 305 * @return the result of taking the given root of this unit. 306 * @throws ArithmeticException if {@code n == 0} or if this operation 307 * would result in an unit with a fractional exponent. 308 */ 309 Unit<?> root(int n); 310 311 /** 312 * Returns a unit equals to this unit raised to an exponent. 313 * 314 * @param n the exponent. 315 * @return the result of raising this unit to the exponent. 316 */ 317 Unit<?> pow(int n); 318 319 /** 320 * Returns the unit derived from this unit using the specified converter. 321 * The converter does not need to be linear. For example:<br> 322 * <code> 323 * Unit<Dimensionless> DECIBEL = Unit.ONE.transform( 324 * new LogConverter(10).inverse().concatenate( 325 * new RationalConverter(1, 10))); 326 * </code> 327 * 328 * @param operation the converter from the transformed unit to this unit. 329 * @return the unit after the specified transformation. 330 */ 331 Unit<Q> transform(UnitConverter converter); 332 333 /** 334 * <p>Returns a string representation of this unit. The string representation may 335 * be the unit {@linkplain #getSymbol() symbol}, or may be some representation 336 * of {@linkplain #getProductUnits() product units}, multiplication factor and 337 * offset if any.</p> 338 * The string may be localized at implementation choice by the means of a particular device and platform. 339 * <br> 340 * @return the string representation of this unit. 341 * 342 * @see #getSymbol() 343 */ 344 @Override 345 String toString(); 346}