001/* 002 * Units of Measurement API 003 * Copyright (c) 2014-2018, 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.3, August 2, 2018 091 * @since 1.0 092 */ 093public interface Quantity<Q extends Quantity<Q>> { 094 095 /** 096 * Returns the sum of this {@code Quantity} with the one specified. 097 * The result shall be as if this quantity and the given addend were 098 * converted to {@linkplain Unit#getSystemUnit() system unit} before 099 * to be added, and the result converted back to the unit of this 100 * quantity or any other compatible unit at implementation choice. 101 * 102 * @param addend 103 * the {@code Quantity} to be added. 104 * @return {@code this + addend}. 105 */ 106 Quantity<Q> add(Quantity<Q> addend); 107 108 /** 109 * Returns the difference between this {@code Quantity} and the one specified. 110 * The result shall be as if this quantity and the given subtrahend were 111 * converted to {@linkplain Unit#getSystemUnit() system unit} before 112 * to be subtracted, and the result converted back to the unit of this 113 * quantity or any other compatible unit at implementation choice. 114 * 115 * @param subtrahend 116 * the {@code Quantity} to be subtracted. 117 * @return <code>this - subtrahend</code>. 118 */ 119 Quantity<Q> subtract(Quantity<Q> subtrahend); 120 121 /** 122 * Returns the product of this {@code Quantity} divided by the {@code Quantity} 123 * specified. 124 * The result shall be as if this quantity and the given divisor were 125 * converted to {@linkplain Unit#getSystemUnit() system unit} before 126 * to be divided, and the result converted back to the unit of this 127 * quantity or any other compatible unit at implementation choice. 128 * 129 * @throws ClassCastException 130 * if the type of an element in the specified operation is 131 * incompatible with this quantity 132 * (<a href="#optional-restrictions">optional</a>) 133 * 134 * @param divisor 135 * the {@code Quantity} divisor. 136 * @return <code>this / divisor</code>. 137 */ 138 Quantity<?> divide(Quantity<?> divisor); 139 140 /** 141 * Returns the product of this {@code Quantity} divided by the {@code Number} 142 * specified. 143 * The result shall be as if this quantity was converted to 144 * {@linkplain Unit#getSystemUnit() system unit} before to be divided, 145 * and the result converted back to the unit of this quantity or any 146 * other compatible unit at implementation choice. 147 * 148 * @param divisor 149 * the {@code Number} divisor. 150 * @return <code>this / divisor</code>. 151 */ 152 Quantity<Q> divide(Number divisor); 153 154 /** 155 * Returns the product of this {@code Quantity} with the one specified. 156 * The result shall be as if this quantity and the given multiplicand were 157 * converted to {@linkplain Unit#getSystemUnit() system unit} before 158 * to be multiplied, and the result converted back to the unit of this 159 * quantity or any other compatible unit at implementation choice. 160 * 161 * @throws ClassCastException 162 * if the type of an element in the specified operation is 163 * incompatible with this quantity 164 * (<a href="#optional-restrictions">optional</a>) 165 * 166 * @param multiplicand 167 * the {@code Quantity} multiplicand. 168 * @return <code>this * multiplicand</code>. 169 */ 170 Quantity<?> multiply(Quantity<?> multiplicand); 171 172 /** 173 * Returns the product of this {@code Quantity} with the {@code Number} value 174 * specified. 175 * The result shall be as if this quantity was converted to 176 * {@linkplain Unit#getSystemUnit() system unit} before to be multiplied, 177 * and the result converted back to the unit of this quantity or any 178 * other compatible unit at implementation choice. 179 * 180 * @param multiplicand 181 * the {@code Number} multiplicand. 182 * @return <code>this * multiplicand</code>. 183 */ 184 Quantity<Q> multiply(Number multiplicand); 185 186 /** 187 * Returns this {@code Quantity} converted into another (compatible) 188 * {@code Unit}. 189 * 190 * @param unit 191 * the {@code Unit} to convert to. 192 * @return the converted result. 193 */ 194 Quantity<Q> to(Unit<Q> unit); 195 196 /** 197 * Returns a {@code Quantity} that is the multiplicative inverse of this 198 * {@code Quantity}, having reciprocal value and reciprocal unit as given by 199 * {@code this.getUnit().inverse()}. 200 * 201 * @return reciprocal {@code Quantity} 202 * @see <a href= 203 * "https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia: 204 * Multiplicative inverse</a> 205 */ 206 Quantity<?> inverse(); 207 208 /** 209 * Returns a {@code Quantity} whose value is {@code (-this.getValue())}. 210 * 211 * @return {@code -this}. 212 */ 213 Quantity<Q> negate(); 214 215 /** 216 * Casts this quantity to a parameterized unit of specified nature or throw a 217 * <code>ClassCastException</code> if the dimension of the specified quantity 218 * and this measure unit's dimension do not match. For example: 219 * <p> 220 * <code> 221 * {@literal Quantity<Length>} length = Quantities.getQuantity("2 km").asType(Length.class); 222 * </code> or <code> 223 * {@literal Quantity<Speed>} C = length.multiply(299792458).divide(second).asType(Speed.class); 224 * </code> 225 * </p> 226 * 227 * @param <T> 228 * The type of the quantity. 229 * @param type 230 * the quantity class identifying the nature of the quantity. 231 * @return this quantity parameterized with the specified type. 232 * @throws ClassCastException 233 * if the dimension of this unit is different from the specified 234 * quantity dimension. 235 * @throws UnsupportedOperationException 236 * if the specified quantity class does not have a SI unit for the 237 * quantity. 238 * @see Unit#asType(Class) 239 */ 240 <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException; 241 242 /** 243 * Returns the value of this {@code Quantity}. 244 * 245 * @return a value. 246 */ 247 Number getValue(); 248 249 /** 250 * Returns the unit of this {@code Quantity}. 251 * 252 * @return the unit (shall not be {@code null}). 253 */ 254 Unit<Q> getUnit(); 255 256 /** 257 * Convenient method equivalent to {@link #to(javax.measure.Unit) 258 * to(getUnit().toSystemUnit())}. 259 * 260 * @return this quantity or a new quantity equivalent to this quantity stated in 261 * SI units. 262 * @throws ArithmeticException 263 * if the result is inexact and the quotient has a non-terminating 264 * decimal expansion. 265 */ 266 default Quantity<Q> toSystemUnit() { 267 return to(getUnit().getSystemUnit()); 268 } 269}