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     */
017    package org.apache.commons.lang.mutable;
018    
019    import org.apache.commons.lang.math.NumberUtils;
020    
021    /**
022     * A mutable <code>float</code> wrapper.
023     * 
024     * @see Float
025     * @since 2.1
026     * @author Apache Software Foundation
027     * @version $Id: MutableFloat.java 905707 2010-02-02 16:59:59Z niallp $
028     */
029    public class MutableFloat extends Number implements Comparable, Mutable {
030    
031        /**
032         * Required for serialization support.
033         * 
034         * @see java.io.Serializable
035         */
036        private static final long serialVersionUID = 5787169186L;
037    
038        /** The mutable value. */
039        private float value;
040    
041        /**
042         * Constructs a new MutableFloat with the default value of zero.
043         */
044        public MutableFloat() {
045            super();
046        }
047    
048        /**
049         * Constructs a new MutableFloat with the specified value.
050         * 
051         * @param value  the initial value to store
052         */
053        public MutableFloat(float value) {
054            super();
055            this.value = value;
056        }
057    
058        /**
059         * Constructs a new MutableFloat with the specified value.
060         * 
061         * @param value  the initial value to store, not null
062         * @throws NullPointerException if the object is null
063         */
064        public MutableFloat(Number value) {
065            super();
066            this.value = value.floatValue();
067        }
068    
069        /**
070         * Constructs a new MutableFloat parsing the given string.
071         * 
072         * @param value  the string to parse, not null
073         * @throws NumberFormatException if the string cannot be parsed into a float
074         * @since 2.5
075         */
076        public MutableFloat(String value) throws NumberFormatException {
077            super();
078            this.value = Float.parseFloat(value);
079        }
080    
081        //-----------------------------------------------------------------------
082        /**
083         * Gets the value as a Float instance.
084         * 
085         * @return the value as a Float, never null
086         */
087        public Object getValue() {
088            return new Float(this.value);
089        }
090    
091        /**
092         * Sets the value.
093         * 
094         * @param value  the value to set
095         */
096        public void setValue(float value) {
097            this.value = value;
098        }
099    
100        /**
101         * Sets the value from any Number instance.
102         * 
103         * @param value  the value to set, not null
104         * @throws NullPointerException if the object is null
105         * @throws ClassCastException if the type is not a {@link Number}
106         */
107        public void setValue(Object value) {
108            setValue(((Number) value).floatValue());
109        }
110    
111        //-----------------------------------------------------------------------
112        /**
113         * Checks whether the float value is the special NaN value.
114         * 
115         * @return true if NaN
116         */
117        public boolean isNaN() {
118            return Float.isNaN(value);
119        }
120    
121        /**
122         * Checks whether the float value is infinite.
123         * 
124         * @return true if infinite
125         */
126        public boolean isInfinite() {
127            return Float.isInfinite(value);
128        }
129    
130        //-----------------------------------------------------------------------
131        /**
132         * Increments the value.
133         *
134         * @since Commons Lang 2.2
135         */
136        public void increment() {
137            value++;
138        }
139    
140        /**
141         * Decrements the value.
142         *
143         * @since Commons Lang 2.2
144         */
145        public void decrement() {
146            value--;
147        }
148    
149        //-----------------------------------------------------------------------
150        /**
151         * Adds a value to the value of this instance.
152         * 
153         * @param operand  the value to add, not null
154         * @since Commons Lang 2.2
155         */
156        public void add(float operand) {
157            this.value += operand;
158        }
159    
160        /**
161         * Adds a value to the value of this instance.
162         * 
163         * @param operand  the value to add, not null
164         * @throws NullPointerException if the object is null
165         * @since Commons Lang 2.2
166         */
167        public void add(Number operand) {
168            this.value += operand.floatValue();
169        }
170    
171        /**
172         * Subtracts a value from the value of this instance.
173         * 
174         * @param operand  the value to subtract
175         * @since Commons Lang 2.2
176         */
177        public void subtract(float operand) {
178            this.value -= operand;
179        }
180    
181        /**
182         * Subtracts a value from the value of this instance.
183         * 
184         * @param operand  the value to subtract, not null
185         * @throws NullPointerException if the object is null
186         * @since Commons Lang 2.2
187         */
188        public void subtract(Number operand) {
189            this.value -= operand.floatValue();
190        }
191    
192        //-----------------------------------------------------------------------
193        // shortValue and bytValue rely on Number implementation
194        /**
195         * Returns the value of this MutableFloat as an int.
196         *
197         * @return the numeric value represented by this object after conversion to type int.
198         */
199        public int intValue() {
200            return (int) value;
201        }
202    
203        /**
204         * Returns the value of this MutableFloat as a long.
205         *
206         * @return the numeric value represented by this object after conversion to type long.
207         */
208        public long longValue() {
209            return (long) value;
210        }
211    
212        /**
213         * Returns the value of this MutableFloat as a float.
214         *
215         * @return the numeric value represented by this object after conversion to type float.
216         */
217        public float floatValue() {
218            return value;
219        }
220    
221        /**
222         * Returns the value of this MutableFloat as a double.
223         *
224         * @return the numeric value represented by this object after conversion to type double.
225         */
226        public double doubleValue() {
227            return value;
228        }
229    
230        //-----------------------------------------------------------------------
231        /**
232         * Gets this mutable as an instance of Float.
233         *
234         * @return a Float instance containing the value from this mutable, never null
235         */
236        public Float toFloat() {
237            return new Float(floatValue());
238        }
239    
240        //-----------------------------------------------------------------------
241        /**
242         * Compares this object against some other object. The result is <code>true</code> if and only if the argument is
243         * not <code>null</code> and is a <code>Float</code> object that represents a <code>float</code> that has the
244         * identical bit pattern to the bit pattern of the <code>float</code> represented by this object. For this
245         * purpose, two float values are considered to be the same if and only if the method
246         * {@link Float#floatToIntBits(float)}returns the same int value when applied to each.
247         * <p>
248         * Note that in most cases, for two instances of class <code>Float</code>,<code>f1</code> and <code>f2</code>,
249         * the value of <code>f1.equals(f2)</code> is <code>true</code> if and only if <blockquote>
250         * 
251         * <pre>
252         *   f1.floatValue() == f2.floatValue()
253         * </pre>
254         * 
255         * </blockquote>
256         * <p>
257         * also has the value <code>true</code>. However, there are two exceptions:
258         * <ul>
259         * <li>If <code>f1</code> and <code>f2</code> both represent <code>Float.NaN</code>, then the
260         * <code>equals</code> method returns <code>true</code>, even though <code>Float.NaN==Float.NaN</code> has
261         * the value <code>false</code>.
262         * <li>If <code>f1</code> represents <code>+0.0f</code> while <code>f2</code> represents <code>-0.0f</code>,
263         * or vice versa, the <code>equal</code> test has the value <code>false</code>, even though
264         * <code>0.0f==-0.0f</code> has the value <code>true</code>.
265         * </ul>
266         * This definition allows hashtables to operate properly.
267         * 
268         * @param obj  the object to compare with, null returns false
269         * @return <code>true</code> if the objects are the same; <code>false</code> otherwise.
270         * @see java.lang.Float#floatToIntBits(float)
271         */
272        public boolean equals(Object obj) {
273            return (obj instanceof MutableFloat)
274                && (Float.floatToIntBits(((MutableFloat) obj).value) == Float.floatToIntBits(value));
275        }
276    
277        /**
278         * Returns a suitable hash code for this mutable.
279         * 
280         * @return a suitable hash code
281         */
282        public int hashCode() {
283            return Float.floatToIntBits(value);
284        }
285    
286        //-----------------------------------------------------------------------
287        /**
288         * Compares this mutable to another in ascending order.
289         * 
290         * @param obj the other mutable to compare to, not null
291         * @return negative if this is less, zero if equal, positive if greater
292         */
293        public int compareTo(Object obj) {
294            MutableFloat other = (MutableFloat) obj;
295            float anotherVal = other.value;
296            return NumberUtils.compare(value, anotherVal);
297        }
298    
299        //-----------------------------------------------------------------------
300        /**
301         * Returns the String value of this mutable.
302         * 
303         * @return the mutable value as a string
304         */
305        public String toString() {
306            return String.valueOf(value);
307        }
308    
309    }