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