    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 float} 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 MutableFloat does not extend Float, it is not treated by String.format as a Float parameter.
    029 * </p>
    030 *
    031 * @see Float
    032 * @see DoubleAccumulator
    033 * @see DoubleAdder
    034 * @since 2.1
    035 */
    036public class MutableFloat extends Number implements Comparable<MutableFloat>, Mutable<Number> {
    037
    038    /**
    039     * Required for serialization support.
    040     *
    041     * @see java.io.Serializable
    042     */
    043    private static final long serialVersionUID = 5787169186L;
    044
    045    /** The mutable value. */
    046    private float value;
    047
    048    /**
    049     * Constructs a new MutableFloat with the default value of zero.
    050     */
    051    public MutableFloat() {
    052    }
    053
    054    /**
    055     * Constructs a new MutableFloat with the specified value.
    056     *
    057     * @param value  the initial value to store.
    058     */
    059    public MutableFloat(final float value) {
    060        this.value = value;
    061    }
    062
    063    /**
    064     * Constructs a new MutableFloat 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 MutableFloat(final Number value) {
    070        this.value = value.floatValue();
    071    }
    072
    073    /**
    074     * Constructs a new MutableFloat 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 float, see {@link Float#parseFloat(String)}.
    078     * @since 2.5
    079     */
    080    public MutableFloat(final String value) {
    081        this.value = Float.parseFloat(value);
    082    }
    083
    084    /**
    085     * Adds a value to the value of this instance.
    086     *
    087     * @param operand  the value to add, not null.
    088     * @since 2.2
    089     */
    090    public void add(final float 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.floatValue();
    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 float addAndGet(final float 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 float addAndGet(final Number operand) {
    128        this.value += operand.floatValue();
    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 MutableFloat other) {
    140        return Float.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 float decrementAndGet() {
    160        value--;
    161        return value;
    162    }
    163
    164    /**
    165     * Returns the value of this MutableFloat 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 some other object. The result is {@code true} if and only if the argument is not {@code null} and is a {@link Float} object
    176     * that represents a {@code float} that has the identical bit pattern to the bit pattern of the {@code float} represented by this object. For this purpose,
    177     * two float values are considered to be the same if and only if the method {@link Float#floatToIntBits(float)}returns the same int value when applied to
    178     * each.
    179     * <p>
    180     * Note that in most cases, for two instances of class {@link Float},{@code f1} and {@code f2}, the value of {@code f1.equals(f2)} is {@code true} if and
    181     * only if:
    182     * </p>
    183     * <pre>
    184     * f1.floatValue() == f2.floatValue()
    185     * </pre>
    186     * <p>
    187     * also has the value {@code true}. However, there are two exceptions:
    188     * </p>
    189     * <ul>
    190     * <li>If {@code f1} and {@code f2} both represent {@code Float.NaN}, then the {@code equals} method returns {@code true}, even though
    191     * {@code Float.NaN == Float.NaN} has the value {@code false}.
    192     * <li>If {@code f1} represents {@code +0.0f} while {@code f2} represents {@code -0.0f}, or vice versa, the {@code equal} test has the value {@code false},
    193     * even though {@code 0.0f == -0.0f} has the value {@code true}.
    194     * </ul>
    195     * <p>
    196     * This definition allows hashtables to operate properly.
    197     * </p>
    198     *
    199     * @param obj the object to compare with, null returns false.
    200     * @return {@code true} if the objects are the same; {@code false} otherwise.
    201     * @see Float#floatToIntBits(float)
    202     */
    203    @Override
    204    public boolean equals(final Object obj) {
    205        return obj instanceof MutableFloat
    206            && Float.floatToIntBits(((MutableFloat) obj).value) == Float.floatToIntBits(value);
    207    }
    208
    209    /**
    210     * Returns the value of this MutableFloat as a float.
    211     *
    212     * @return the numeric value represented by this object after conversion to type float.
    213     */
    214    @Override
    215    public float floatValue() {
    216        return value;
    217    }
    218
    219    /**
    220     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    221     * immediately prior to the addition operation. This method is not thread safe.
    222     *
    223     * @param operand the quantity to add, not null.
    224     * @return the value associated with this instance immediately before the operand was added.
    225     * @since 3.5
    226     */
    227    public float getAndAdd(final float operand) {
    228        final float last = value;
    229        this.value += operand;
    230        return last;
    231    }
    232
    233    /**
    234     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    235     * immediately prior to the addition operation. This method is not thread safe.
    236     *
    237     * @param operand the quantity to add, not null.
    238     * @throws NullPointerException if {@code operand} is null.
    239     * @return the value associated with this instance immediately before the operand was added.
    240     * @since 3.5
    241     */
    242    public float getAndAdd(final Number operand) {
    243        final float last = value;
    244        this.value += operand.floatValue();
    245        return last;
    246    }
    247
    248    /**
    249     * Decrements this instance's value by 1; this method returns the value associated with the instance
    250     * immediately prior to the decrement operation. This method is not thread safe.
    251     *
    252     * @return the value associated with the instance before it was decremented.
    253     * @since 3.5
    254     */
    255    public float getAndDecrement() {
    256        final float last = value;
    257        value--;
    258        return last;
    259    }
    260
    261    /**
    262     * Increments this instance's value by 1; this method returns the value associated with the instance
    263     * immediately prior to the increment operation. This method is not thread safe.
    264     *
    265     * @return the value associated with the instance before it was incremented.
    266     * @since 3.5
    267     */
    268    public float getAndIncrement() {
    269        final float last = value;
    270        value++;
    271        return last;
    272    }
    273
    274    /**
    275     * Gets the value as a Float instance.
    276     *
    277     * @return the value as a Float, never null.
    278     * @deprecated Use {@link #get()}.
    279     */
    280    @Deprecated
    281    @Override
    282    public Float getValue() {
    283        return Float.valueOf(this.value);
    284    }
    285
    286    /**
    287     * Returns a suitable hash code for this mutable.
    288     *
    289     * @return a suitable hash code.
    290     */
    291    @Override
    292    public int hashCode() {
    293        return Float.floatToIntBits(value);
    294    }
    295
    296    /**
    297     * Increments the value.
    298     *
    299     * @since 2.2
    300     */
    301    public void increment() {
    302        value++;
    303    }
    304
    305    /**
    306     * Increments this instance's value by 1; this method returns the value associated with the instance
    307     * immediately after the increment operation. This method is not thread safe.
    308     *
    309     * @return the value associated with the instance after it is incremented.
    310     * @since 3.5
    311     */
    312    public float incrementAndGet() {
    313        value++;
    314        return value;
    315    }
    316
    317    // shortValue and byteValue rely on Number implementation
    318    /**
    319     * Returns the value of this MutableFloat as an int.
    320     *
    321     * @return the numeric value represented by this object after conversion to type int.
    322     */
    323    @Override
    324    public int intValue() {
    325        return (int) value;
    326    }
    327
    328    /**
    329     * Checks whether the float value is infinite.
    330     *
    331     * @return true if infinite
    332     */
    333    public boolean isInfinite() {
    334        return Float.isInfinite(value);
    335    }
    336
    337    /**
    338     * Checks whether the float value is the special NaN value.
    339     *
    340     * @return true if NaN.
    341     */
    342    public boolean isNaN() {
    343        return Float.isNaN(value);
    344    }
    345
    346    /**
    347     * Returns the value of this MutableFloat as a long.
    348     *
    349     * @return the numeric value represented by this object after conversion to type long.
    350     */
    351    @Override
    352    public long longValue() {
    353        return (long) value;
    354    }
    355
    356    /**
    357     * Sets the value.
    358     *
    359     * @param value  the value to set.
    360     */
    361    public void setValue(final float value) {
    362        this.value = value;
    363    }
    364
    365    /**
    366     * Sets the value from any Number instance.
    367     *
    368     * @param value  the value to set, not null.
    369     * @throws NullPointerException if the object is null.
    370     */
    371    @Override
    372    public void setValue(final Number value) {
    373        this.value = value.floatValue();
    374    }
    375
    376    /**
    377     * Subtracts a value from the value of this instance.
    378     *
    379     * @param operand  the value to subtract.
    380     * @since 2.2
    381     */
    382    public void subtract(final float operand) {
    383        this.value -= operand;
    384    }
    385
    386    /**
    387     * Subtracts a value from the value of this instance.
    388     *
    389     * @param operand  the value to subtract, not null.
    390     * @throws NullPointerException if the object is null.
    391     * @since 2.2
    392     */
    393    public void subtract(final Number operand) {
    394        this.value -= operand.floatValue();
    395    }
    396
    397    /**
    398     * Gets this mutable as an instance of Float.
    399     *
    400     * @return a Float instance containing the value from this mutable, never null.
    401     */
    402    public Float toFloat() {
    403        return Float.valueOf(floatValue());
    404    }
    405
    406    /**
    407     * Returns the String value of this mutable.
    408     *
    409     * @return the mutable value as a string.
    410     */
    411    @Override
    412    public String toString() {
    413        return String.valueOf(value);
    414    }
    415
    416}