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