001/* 002 * Units of Measurement API 003 * Copyright (c) 2014-2021, 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 */ 030package javax.measure; 031 032/** 033 * Represents a quantitative property of a phenomenon, body, or substance, that 034 * can be quantified by measurement. {@link javax.measure.quantity.Mass Mass}, 035 * time, distance, heat, and angular separation are among the familiar examples 036 * of quantitative properties. 037 * <p> 038 * <code> {@literal Unit<Mass>} pound = ... {@literal Quantity<Length>} size = ... {@literal Sensor<Temperature>}<br> 039 * thermometer = ... {@literal Vector3D<Speed>} aircraftSpeed = ... </code> 040 * </p> 041 * 042 * <dl> 043 * <dt><span class="strong">Arithmetic operations</span></dt> 044 * </dl> 045 * This interface defines some arithmetic operations between {@code Quantity} 046 * instances. All implementations shall produce <em>equivalent</em> results for 047 * the same operation applied on equivalent quantities. Two quantities are 048 * equivalent if, after conversion to the same unit of measurement, they have 049 * the same numerical value (ignoring rounding errors). For example 2000 metres 050 * is equivalent to 2 km, but 2°C is not equivalent to 2 K; it is equivalent to 051 * 275.15 K instead. Above requirement applied to addition means that 2°C + 2 K 052 * shall be equivalent to 275.15 K + 2 K. 053 * 054 * <p>All operations shall preserve the 055 * <a href="https://en.wikiversity.org/wiki/Basic_Laws_of_Algebra">basic laws 056 * of algebra</a>, in particular <b>commutativity</b> of addition and 057 * multiplication (<var>A</var> + <var>B</var> = <var>B</var> + <var>A</var>) 058 * and <b>associativity</b> of addition and multiplication (<var>A</var> + 059 * <var>B</var>) + <var>C</var> = <var>A</var> + (<var>B</var> + <var>C</var>). 060 * In order to preserve those algebra laws, this specification requires all 061 * arithmetic operations to execute <em>as is</em> all operands were converted 062 * to {@linkplain Unit#getSystemUnit() system unit} before the operation is 063 * carried out, and the result converted back to any compatible unit at 064 * implementation choice. For example 4 cm + 1 inch shall produce any result 065 * <em>equivalent</em> to 0.04 m + 0.0254 m.</p> 066 * 067 * <p>Implementations are allowed to avoid conversion to system unit if the 068 * result is guaranteed to be equivalent. This is often the case when the 069 * conversion between quantity unit and system unit is only a 070 * {@linkplain UnitConverter#isLinear() scale factor}. However this is not 071 * the case for conversions applying an offset or more complex formula. 072 * For example 2°C + 1°C = 274.15°C, not 3°C. This counter-intuitive result 073 * is essential for preserving algebra laws like associativity, and is also 074 * the expected result from a thermodynamic point of view.</p> 075 * 076 * <dl> 077 * <dt><span class="strong">API Note:</span></dt><dd>This interface places no restrictions on the mutability of 078 * implementations, however immutability is strongly recommended. All 079 * implementations must be {@link Comparable}.</dd> 080 * </dl> 081 * 082 * @param <Q> 083 * The type of the quantity. 084 * 085 * @author <a href="mailto:[email protected]">Jean-Marie Dautelle</a> 086 * @author <a href="mailto:[email protected]">Martin 087 * Desruisseaux</a> 088 * @author <a href="mailto:[email protected]">Werner Keil</a> 089 * @author <a href="mailto:[email protected]">Otavio Santana</a> 090 * @see Unit 091 * @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a> 092 * @see <a href="http://martinfowler.com/eaaDev/quantity.html">Martin Fowler - 093 * Quantity</a> 094 * @version 2.3, September 28, 2020 095 * @since 1.0 096 */ 097public interface Quantity<Q extends Quantity<Q>> { 098 099 /** 100 * The scale of a {@link Quantity}, either {@code ABSOLUTE} or {@code RELATIVE}. 101 * 102 * @since 2.0 103 * @see <a href="https://en.wikipedia.org/wiki/Absolute_scale">Wikipedia: Absolute scale</a> 104 */ 105 public static enum Scale { 106 ABSOLUTE, RELATIVE 107 } 108 109 /** 110 * Returns the sum of this {@code Quantity} with the one specified. 111 * The result shall be as if this quantity and the given addend were 112 * converted to {@linkplain Unit#getSystemUnit() system unit} before 113 * to be added, and the result converted back to the unit of this 114 * quantity or any other compatible unit at implementation choice. 115 * 116 * @param addend 117 * the {@code Quantity} to be added. 118 * @return {@code this + addend}. 119 */ 120 Quantity<Q> add(Quantity<Q> addend); 121 122 /** 123 * Returns the difference between this {@code Quantity} and the one specified. 124 * The result shall be as if this quantity and the given subtrahend were 125 * converted to {@linkplain Unit#getSystemUnit() system unit} before 126 * to be subtracted, and the result converted back to the unit of this 127 * quantity or any other compatible unit at implementation choice. 128 * 129 * @param subtrahend 130 * the {@code Quantity} to be subtracted. 131 * @return <code>this - subtrahend</code>. 132 */ 133 Quantity<Q> subtract(Quantity<Q> subtrahend); 134 135 /** 136 * Returns the quotient of this {@code Quantity} divided by the {@code Quantity} 137 * specified. 138 * The result shall be as if this quantity and the given divisor were 139 * converted to {@linkplain Unit#getSystemUnit() system unit} before 140 * to be divided, and the result converted back to the unit of this 141 * quantity or any other compatible unit at implementation choice. 142 * 143 * @throws ClassCastException 144 * if the type of an element in the specified operation is 145 * incompatible with this quantity 146 * 147 * @param divisor 148 * the {@code Quantity} divisor. 149 * @return <code>this / divisor</code>. 150 */ 151 Quantity<?> divide(Quantity<?> divisor); 152 153 /** 154 * Returns the quotient of this {@code Quantity} divided by the {@code Number} 155 * specified. 156 * The result shall be as if this quantity was converted to 157 * {@linkplain Unit#getSystemUnit() system unit} before to be divided, 158 * and the result converted back to the unit of this quantity or any 159 * other compatible unit at implementation choice. 160 * 161 * @param divisor 162 * the {@code Number} divisor. 163 * @return <code>this / divisor</code>. 164 */ 165 Quantity<Q> divide(Number divisor); 166 167 /** 168 * Returns the product of this {@code Quantity} with the one specified. 169 * The result shall be as if this quantity and the given multiplicand were 170 * converted to {@linkplain Unit#getSystemUnit() system unit} before 171 * to be multiplied, and the result converted back to the unit of this 172 * quantity or any other compatible unit at implementation choice. 173 * 174 * @throws ClassCastException 175 * if the type of an element in the specified operation is 176 * incompatible with this quantity 177 * 178 * @param multiplicand 179 * the {@code Quantity} multiplicand. 180 * @return <code>this * multiplicand</code>. 181 */ 182 Quantity<?> multiply(Quantity<?> multiplicand); 183 184 /** 185 * Returns the product of this {@code Quantity} with the {@code Number} value 186 * specified. 187 * The result shall be as if this quantity was converted to 188 * {@linkplain Unit#getSystemUnit() system unit} before to be multiplied, 189 * and the result converted back to the unit of this quantity or any 190 * other compatible unit at implementation choice. 191 * 192 * @param multiplicand 193 * the {@code Number} multiplicand. 194 * @return <code>this * multiplicand</code>. 195 */ 196 Quantity<Q> multiply(Number multiplicand); 197 198 /** 199 * Returns this {@code Quantity} converted into another (compatible) 200 * {@code Unit}. 201 * 202 * @param unit 203 * the {@code Unit unit} in which the returned quantity is stated. 204 * @return this quantity or a new quantity equivalent to this quantity stated in the specified unit. 205 * @throws ArithmeticException 206 * if the result is inexact and the quotient has a non-terminating decimal expansion. 207 */ 208 Quantity<Q> to(Unit<Q> unit); 209 210 /** 211 * Returns a {@code Quantity} that is the multiplicative inverse of this 212 * {@code Quantity}, having reciprocal value and reciprocal unit as given by 213 * {@code this.getUnit().inverse()}. 214 * 215 * @return reciprocal {@code Quantity} 216 * @see <a href= 217 * "https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia: 218 * Multiplicative inverse</a> 219 */ 220 Quantity<?> inverse(); 221 222 /** 223 * Returns a {@code Quantity} whose value is {@code (-this.getValue())}. 224 * 225 * @return {@code -this}. 226 */ 227 Quantity<Q> negate(); 228 229 /** 230 * Casts this quantity to a parameterized unit of specified nature or throw a 231 * <code>ClassCastException</code> if the dimension of the specified quantity 232 * and this measure unit's dimension do not match. For example: 233 * <p> 234 * <code> 235 * {@literal Quantity<Length>} length = Quantities.getQuantity("2 km").asType(Length.class); 236 * </code> or <code> 237 * {@literal Quantity<Speed>} C = length.multiply(299792458).divide(second).asType(Speed.class); 238 * </code> 239 * </p> 240 * 241 * @param <T> 242 * The type of the quantity. 243 * @param type 244 * the quantity class identifying the nature of the quantity. 245 * @return this quantity parameterized with the specified type. 246 * @throws ClassCastException 247 * if the dimension of this unit is different from the specified 248 * quantity dimension. 249 * @throws UnsupportedOperationException 250 * if the specified quantity class does not have a SI unit for the 251 * quantity. 252 * @see Unit#asType(Class) 253 */ 254 <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException; 255 256 /** 257 * Returns the value of this {@code Quantity}. 258 * 259 * @return a value. 260 */ 261 Number getValue(); 262 263 /** 264 * Returns the unit of this {@code Quantity}. 265 * 266 * @return the unit (shall not be {@code null}). 267 */ 268 Unit<Q> getUnit(); 269 270 /** 271 * Convenient method equivalent to {@link #to(javax.measure.Unit) 272 * to(getUnit().toSystemUnit())}. 273 * 274 * @return this quantity or a new quantity equivalent to this quantity stated in 275 * SI units. 276 * @throws ArithmeticException 277 * if the result is inexact and the quotient has a non-terminating 278 * decimal expansion. 279 */ 280 default Quantity<Q> toSystemUnit() { 281 return to(getUnit().getSystemUnit()); 282 } 283 284 /** 285 * Returns the {@code Scale} of this {@code Quantity}, if it's absolute or relative. 286 * 287 * @return the scale, if it's an absolute or relative quantity. 288 * @since 2.0 289 290 * @see <a href="https://en.wikipedia.org/wiki/Absolute_scale">Wikipedia: Absolute scale</a> 291 */ 292 Scale getScale(); 293 294 /** 295 * Compares two instances of {@code Quantity <Q>}, doing the conversion of unit if necessary. 296 * 297 * @param that 298 * the {@code quantity<Q>} to be compared with this instance. 299 * @return {@code true} if {@code that \u2261 this}. 300 * @throws NullPointerException 301 * if the quantity is null 302 * 303 * @see <a href= "https://dictionary.cambridge.org/dictionary/english/equivalent">Cambridge Dictionary: equivalent</a> 304 * @see <a href= "https://www.lexico.com/en/definition/equivalent">LEXICO: equivalent</a> 305 * @since 2.1 306 */ 307 boolean isEquivalentTo(Quantity<Q> that); 308}