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