    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.lang3.mutable;
    018
    019import java.util.concurrent.atomic.DoubleAccumulator;
    020import java.util.concurrent.atomic.DoubleAdder;
    021
    022/**
    023 * A mutable {@code double} wrapper.
    024 * <p>
    025 * This class was created before the introduction of the the {@link java.util.concurrent.atomic} package and the {@link DoubleAccumulator} class.
    026 * </p>
    027 * <p>
    028 * Note that as MutableDouble does not extend Double, it is not treated by String.format as a Double parameter.
    029 * </p>
    030 *
    031 * @see Double
    032 * @see DoubleAccumulator
    033 * @see DoubleAdder
    034 * @since 2.1
    035 */
    036public class MutableDouble extends Number implements Comparable<MutableDouble>, Mutable<Number> {
    037
    038    /**
    039     * Required for serialization support.
    040     *
    041     * @see java.io.Serializable
    042     */
    043    private static final long serialVersionUID = 1587163916L;
    044
    045    /** The mutable value. */
    046    private double value;
    047
    048    /**
    049     * Constructs a new MutableDouble with the default value of zero.
    050     */
    051    public MutableDouble() {
    052    }
    053
    054    /**
    055     * Constructs a new MutableDouble with the specified value.
    056     *
    057     * @param value  the initial value to store.
    058     */
    059    public MutableDouble(final double value) {
    060        this.value = value;
    061    }
    062
    063    /**
    064     * Constructs a new MutableDouble with the specified value.
    065     *
    066     * @param value  the initial value to store, not null.
    067     * @throws NullPointerException if the object is null.
    068     */
    069    public MutableDouble(final Number value) {
    070        this.value = value.doubleValue();
    071    }
    072
    073    /**
    074     * Constructs a new MutableDouble parsing the given string.
    075     *
    076     * @param value  the string to parse, not null.
    077     * @throws NumberFormatException if the string cannot be parsed into a double, see {@link Double#parseDouble(String)}.
    078     * @since 2.5
    079     */
    080    public MutableDouble(final String value) {
    081        this.value = Double.parseDouble(value);
    082    }
    083
    084    /**
    085     * Adds a value to the value of this instance.
    086     *
    087     * @param operand  the value to add.
    088     * @since 2.2
    089     */
    090    public void add(final double operand) {
    091        this.value += operand;
    092    }
    093
    094    /**
    095     * Adds a value to the value of this instance.
    096     *
    097     * @param operand  the value to add, not null.
    098     * @throws NullPointerException if the object is null.
    099     * @since 2.2
    100     */
    101    public void add(final Number operand) {
    102        this.value += operand.doubleValue();
    103    }
    104
    105    /**
    106     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    107     * immediately after the addition operation. This method is not thread safe.
    108     *
    109     * @param operand the quantity to add, not null.
    110     * @return the value associated with this instance after adding the operand.
    111     * @since 3.5
    112     */
    113    public double addAndGet(final double operand) {
    114        this.value += operand;
    115        return value;
    116    }
    117
    118    /**
    119     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    120     * immediately after the addition operation. This method is not thread safe.
    121     *
    122     * @param operand the quantity to add, not null.
    123     * @throws NullPointerException if {@code operand} is null.
    124     * @return the value associated with this instance after adding the operand.
    125     * @since 3.5
    126     */
    127    public double addAndGet(final Number operand) {
    128        this.value += operand.doubleValue();
    129        return value;
    130    }
    131
    132    /**
    133     * Compares this mutable to another in ascending order.
    134     *
    135     * @param other  the other mutable to compare to, not null.
    136     * @return negative if this is less, zero if equal, positive if greater.
    137     */
    138    @Override
    139    public int compareTo(final MutableDouble other) {
    140        return Double.compare(this.value, other.value);
    141    }
    142
    143    /**
    144     * Decrements the value.
    145     *
    146     * @since 2.2
    147     */
    148    public void decrement() {
    149        value--;
    150    }
    151
    152    /**
    153     * Decrements this instance's value by 1; this method returns the value associated with the instance
    154     * immediately after the decrement operation. This method is not thread safe.
    155     *
    156     * @return the value associated with the instance after it is decremented.
    157     * @since 3.5
    158     */
    159    public double decrementAndGet() {
    160        value--;
    161        return value;
    162    }
    163
    164    /**
    165     * Returns the value of this MutableDouble as a double.
    166     *
    167     * @return the numeric value represented by this object after conversion to type double.
    168     */
    169    @Override
    170    public double doubleValue() {
    171        return value;
    172    }
    173
    174    /**
    175     * Compares this object against the specified object. The result is {@code true} if and only if the argument is not {@code null} and is a {@link Double}
    176     * object that represents a double that has the identical bit pattern to the bit pattern of the double represented by this object. For this purpose, two
    177     * {@code double} values are considered to be the same if and only if the method {@link Double#doubleToLongBits(double)}returns the same long value when
    178     * applied to each.
    179     * <p>
    180     * Note that in most cases, for two instances of class {@link Double},{@code d1} and {@code d2}, the value of {@code d1.equals(d2)} is {@code true} if and
    181     * only if:
    182     * </p>
    183     * <pre>
    184     * d1.doubleValue() == d2.doubleValue()
    185     * </pre>
    186     * <p>
    187     * also has the value {@code true}. However, there are two exceptions:
    188     * </p>
    189     * <ul>
    190     * <li>If {@code d1} and {@code d2} both represent {@code Double.NaN}, then the {@code equals} method returns {@code true}, even though
    191     * {@code Double.NaN == Double.NaN} has the value {@code false}.
    192     * <li>If {@code d1} represents {@code +0.0} while {@code d2} represents {@code -0.0}, or vice versa, the {@code equal} test has the value {@code false},
    193     * even though {@code +0.0 == -0.0} has the value {@code true}. This allows hashtables to operate properly.
    194     * </ul>
    195     *
    196     * @param obj the object to compare with, null returns false.
    197     * @return {@code true} if the objects are the same; {@code false} otherwise.
    198     */
    199    @Override
    200    public boolean equals(final Object obj) {
    201        return obj instanceof MutableDouble
    202            && Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value);
    203    }
    204
    205    /**
    206     * Returns the value of this MutableDouble as a float.
    207     *
    208     * @return the numeric value represented by this object after conversion to type float.
    209     */
    210    @Override
    211    public float floatValue() {
    212        return (float) value;
    213    }
    214
    215    /**
    216     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    217     * immediately prior to the addition operation. This method is not thread safe.
    218     *
    219     * @param operand the quantity to add, not null.
    220     * @return the value associated with this instance immediately before the operand was added.
    221     * @since 3.5
    222     */
    223    public double getAndAdd(final double operand) {
    224        final double last = value;
    225        this.value += operand;
    226        return last;
    227    }
    228
    229    /**
    230     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    231     * immediately prior to the addition operation. This method is not thread safe.
    232     *
    233     * @param operand the quantity to add, not null.
    234     * @throws NullPointerException if {@code operand} is null.
    235     * @return the value associated with this instance immediately before the operand was added.
    236     * @since 3.5
    237     */
    238    public double getAndAdd(final Number operand) {
    239        final double last = value;
    240        this.value += operand.doubleValue();
    241        return last;
    242    }
    243
    244    /**
    245     * Decrements this instance's value by 1; this method returns the value associated with the instance
    246     * immediately prior to the decrement operation. This method is not thread safe.
    247     *
    248     * @return the value associated with the instance before it was decremented.
    249     * @since 3.5
    250     */
    251    public double getAndDecrement() {
    252        final double last = value;
    253        value--;
    254        return last;
    255    }
    256
    257    /**
    258     * Increments this instance's value by 1; this method returns the value associated with the instance
    259     * immediately prior to the increment operation. This method is not thread safe.
    260     *
    261     * @return the value associated with the instance before it was incremented.
    262     * @since 3.5
    263     */
    264    public double getAndIncrement() {
    265        final double last = value;
    266        value++;
    267        return last;
    268    }
    269
    270    /**
    271     * Gets the value as a Double instance.
    272     *
    273     * @return the value as a Double, never null.
    274     * @deprecated Use {@link #get()}.
    275     */
    276    @Deprecated
    277    @Override
    278    public Double getValue() {
    279        return Double.valueOf(this.value);
    280    }
    281
    282    /**
    283     * Returns a suitable hash code for this mutable.
    284     *
    285     * @return a suitable hash code.
    286     */
    287    @Override
    288    public int hashCode() {
    289        final long bits = Double.doubleToLongBits(value);
    290        return (int) (bits ^ bits >>> 32);
    291    }
    292
    293    /**
    294     * Increments the value.
    295     *
    296     * @since 2.2
    297     */
    298    public void increment() {
    299        value++;
    300    }
    301
    302    /**
    303     * Increments this instance's value by 1; this method returns the value associated with the instance
    304     * immediately after the increment operation. This method is not thread safe.
    305     *
    306     * @return the value associated with the instance after it is incremented.
    307     * @since 3.5
    308     */
    309    public double incrementAndGet() {
    310        value++;
    311        return value;
    312    }
    313
    314    // shortValue and byteValue rely on Number implementation
    315    /**
    316     * Returns the value of this MutableDouble as an int.
    317     *
    318     * @return the numeric value represented by this object after conversion to type int.
    319     */
    320    @Override
    321    public int intValue() {
    322        return (int) value;
    323    }
    324
    325    /**
    326     * Checks whether the double value is infinite.
    327     *
    328     * @return true if infinite.
    329     */
    330    public boolean isInfinite() {
    331        return Double.isInfinite(value);
    332    }
    333
    334    /**
    335     * Checks whether the double value is the special NaN value.
    336     *
    337     * @return true if NaN.
    338     */
    339    public boolean isNaN() {
    340        return Double.isNaN(value);
    341    }
    342
    343    /**
    344     * Returns the value of this MutableDouble as a long.
    345     *
    346     * @return the numeric value represented by this object after conversion to type long.
    347     */
    348    @Override
    349    public long longValue() {
    350        return (long) value;
    351    }
    352
    353    /**
    354     * Sets the value.
    355     *
    356     * @param value  the value to set.
    357     */
    358    public void setValue(final double value) {
    359        this.value = value;
    360    }
    361
    362    /**
    363     * Sets the value from any Number instance.
    364     *
    365     * @param value  the value to set, not null.
    366     * @throws NullPointerException if the object is null.
    367     */
    368    @Override
    369    public void setValue(final Number value) {
    370        this.value = value.doubleValue();
    371    }
    372
    373    /**
    374     * Subtracts a value from the value of this instance.
    375     *
    376     * @param operand  the value to subtract, not null.
    377     * @since 2.2
    378     */
    379    public void subtract(final double operand) {
    380        this.value -= operand;
    381    }
    382
    383    /**
    384     * Subtracts a value from the value of this instance.
    385     *
    386     * @param operand  the value to subtract, not null.
    387     * @throws NullPointerException if the object is null.
    388     * @since 2.2
    389     */
    390    public void subtract(final Number operand) {
    391        this.value -= operand.doubleValue();
    392    }
    393
    394    /**
    395     * Gets this mutable as an instance of Double.
    396     *
    397     * @return a Double instance containing the value from this mutable, never null.
    398     */
    399    public Double toDouble() {
    400        return Double.valueOf(doubleValue());
    401    }
    402
    403    /**
    404     * Returns the String value of this mutable.
    405     *
    406     * @return the mutable value as a string.
    407     */
    408    @Override
    409    public String toString() {
    410        return String.valueOf(value);
    411    }
    412
    413}