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 */ 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:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 086 * @author <a href="mailto:martin.desruisseaux@geomatys.com">Martin 087 * Desruisseaux</a> 088 * @author <a href="mailto:werner@uom.technology">Werner Keil</a> 089 * @author <a href="mailto:otaviopolianasantana@gmail.com">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.5, May 20, 2023 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 /** 107 * Absolute scale 108 * @see <a href="https://en.wikipedia.org/wiki/Absolute_scale">Wikipedia: Absolute scale</a> 109 */ 110 ABSOLUTE, 111 /** 112 * Relative scale 113 */ 114 RELATIVE 115 } 116 117 /** 118 * Returns the sum of this {@code Quantity} with the one specified. 119 * The result shall be as if this quantity and the given addend were 120 * converted to {@linkplain Unit#getSystemUnit() system unit} before 121 * to be added, and the result converted back to the unit of this 122 * quantity or any other compatible unit at implementation choice. 123 * 124 * @param addend 125 * the {@code Quantity} to be added. 126 * @return {@code this + addend}. 127 */ 128 Quantity<Q> add(Quantity<Q> addend); 129 130 /** 131 * Returns the difference between this {@code Quantity} and the one specified. 132 * The result shall be as if this quantity and the given subtrahend were 133 * converted to {@linkplain Unit#getSystemUnit() system unit} before 134 * to be subtracted, and the result converted back to the unit of this 135 * quantity or any other compatible unit at implementation choice. 136 * 137 * @param subtrahend 138 * the {@code Quantity} to be subtracted. 139 * @return <code>this - subtrahend</code>. 140 */ 141 Quantity<Q> subtract(Quantity<Q> subtrahend); 142 143 /** 144 * Returns the quotient of this {@code Quantity} divided by the {@code Quantity} 145 * specified. 146 * The result shall be as if this quantity and the given divisor were 147 * converted to {@linkplain Unit#getSystemUnit() system unit} before 148 * to be divided, and the result converted back to the unit of this 149 * quantity or any other compatible unit at implementation choice. 150 * 151 * @throws ClassCastException 152 * if the type of an element in the specified operation is 153 * incompatible with this quantity 154 * 155 * @param divisor 156 * the {@code Quantity} divisor. 157 * @return <code>this / divisor</code>. 158 */ 159 Quantity<?> divide(Quantity<?> divisor); 160 161 /** 162 * Returns the quotient of this {@code Quantity} divided by the {@code Number} 163 * specified. 164 * The result shall be as if this quantity was converted to 165 * {@linkplain Unit#getSystemUnit() system unit} before to be divided, 166 * and the result converted back to the unit of this quantity or any 167 * other compatible unit at implementation choice. 168 * 169 * @param divisor 170 * the {@code Number} divisor. 171 * @return <code>this / divisor</code>. 172 */ 173 Quantity<Q> divide(Number divisor); 174 175 /** 176 * Returns the product of this {@code Quantity} with the one specified. 177 * The result shall be as if this quantity and the given multiplicand were 178 * converted to {@linkplain Unit#getSystemUnit() system unit} before 179 * to be multiplied, and the result converted back to the unit of this 180 * quantity or any other compatible unit at implementation choice. 181 * 182 * @throws ClassCastException 183 * if the type of an element in the specified operation is 184 * incompatible with this quantity 185 * 186 * @param multiplicand 187 * the {@code Quantity} multiplicand. 188 * @return <code>this * multiplicand</code>. 189 */ 190 Quantity<?> multiply(Quantity<?> multiplicand); 191 192 /** 193 * Returns the product of this {@code Quantity} with the {@code Number} value 194 * specified. 195 * The result shall be as if this quantity was converted to 196 * {@linkplain Unit#getSystemUnit() system unit} before to be multiplied, 197 * and the result converted back to the unit of this quantity or any 198 * other compatible unit at implementation choice. 199 * 200 * @param multiplicand 201 * the {@code Number} multiplicand. 202 * @return <code>this * multiplicand</code>. 203 */ 204 Quantity<Q> multiply(Number multiplicand); 205 206 /** 207 * Returns this {@code Quantity} converted into another (compatible) 208 * {@code Unit}. 209 * 210 * @param unit 211 * the {@code Unit unit} in which the returned quantity is stated. 212 * @return this quantity or a new quantity equivalent to this quantity stated in the specified unit. 213 * @throws ArithmeticException 214 * if the result is inexact and the quotient has a non-terminating decimal expansion. 215 */ 216 Quantity<Q> to(Unit<Q> unit); 217 218 /** 219 * Returns a {@code Quantity} that is the multiplicative inverse of this 220 * {@code Quantity}, having reciprocal value and reciprocal unit as given by 221 * {@code this.getUnit().inverse()}. 222 * 223 * @return reciprocal {@code Quantity} 224 * @see <a href= 225 * "https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia: 226 * Multiplicative inverse</a> 227 */ 228 Quantity<?> inverse(); 229 230 /** 231 * Returns a {@code Quantity} whose value is {@code (-this.getValue())}. 232 * 233 * @return {@code -this}. 234 */ 235 Quantity<Q> negate(); 236 237 /** 238 * Casts this quantity to a parameterized unit of specified nature or throw a 239 * <code>ClassCastException</code> if the dimension of the specified quantity 240 * and this measure unit's dimension do not match. For example: 241 * <p> 242 * <code> 243 * {@literal Quantity<Length>} length = Quantities.getQuantity("2 km").asType(Length.class); 244 * </code> or <code> 245 * {@literal Quantity<Speed>} C = length.multiply(299792458).divide(second).asType(Speed.class); 246 * </code> 247 * </p> 248 * 249 * @param <T> 250 * The type of the quantity. 251 * @param type 252 * the quantity class identifying the nature of the quantity. 253 * @return this quantity parameterized with the specified type. 254 * @throws ClassCastException 255 * if the dimension of this unit is different from the specified 256 * quantity dimension. 257 * @throws UnsupportedOperationException 258 * if the specified quantity class does not have a SI unit for the 259 * quantity. 260 * @see Unit#asType(Class) 261 */ 262 <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException; 263 264 /** 265 * Returns the value of this {@code Quantity}. 266 * 267 * @return a value. 268 */ 269 Number getValue(); 270 271 /** 272 * Returns the unit of this {@code Quantity}. 273 * 274 * @return the unit (shall not be {@code null}). 275 */ 276 Unit<Q> getUnit(); 277 278 /** 279 * Convenient method equivalent to {@link #to(javax.measure.Unit) 280 * to(getUnit().toSystemUnit())}. 281 * 282 * @return this quantity or a new quantity equivalent to this quantity stated in 283 * SI units. 284 * @throws ArithmeticException 285 * if the result is inexact and the quotient has a non-terminating 286 * decimal expansion. 287 */ 288 default Quantity<Q> toSystemUnit() { 289 return to(getUnit().getSystemUnit()); 290 } 291 292 /** 293 * Returns the {@code Scale} of this {@code Quantity}, if it's absolute or relative. 294 * 295 * @return the scale, if it's an absolute or relative quantity. 296 * @since 2.0 297 298 * @see <a href="https://en.wikipedia.org/wiki/Absolute_scale">Wikipedia: Absolute scale</a> 299 */ 300 Scale getScale(); 301 302 /** 303 * Compares two instances of {@code Quantity <Q>}, performing the conversion of units if necessary. 304 * 305 * @param that 306 * the {@code quantity<Q>} to be compared with this instance. 307 * @return {@code true} if {@code that \u2261 this}. 308 * @throws NullPointerException 309 * if the quantity is null 310 * 311 * @see <a href= "https://dictionary.cambridge.org/dictionary/english/equivalent">Cambridge Dictionary: equivalent</a> 312 * @see <a href= "https://www.lexico.com/en/definition/equivalent">LEXICO: equivalent</a> 313 * @since 2.1 314 */ 315 boolean isEquivalentTo(Quantity<Q> that); 316}