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