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: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.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}