View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3.mutable;
18  
19  import java.util.concurrent.atomic.DoubleAccumulator;
20  import java.util.concurrent.atomic.DoubleAdder;
21  
22  /**
23   * A mutable {@code float} wrapper.
24   * <p>
25   * This class was created before the introduction of the {@link java.util.concurrent.atomic} package and the {@link DoubleAccumulator} class.
26   * </p>
27   * <p>
28   * Note that as MutableFloat does not extend Float, it is not treated by String.format as a Float parameter.
29   * </p>
30   *
31   * @see Float
32   * @see DoubleAccumulator
33   * @see DoubleAdder
34   * @since 2.1
35   */
36  public class MutableFloat extends Number implements Comparable<MutableFloat>, Mutable<Number> {
37  
38      /**
39       * Required for serialization support.
40       *
41       * @see java.io.Serializable
42       */
43      private static final long serialVersionUID = 5787169186L;
44  
45      /** The mutable value. */
46      private float value;
47  
48      /**
49       * Constructs a new MutableFloat with the default value of zero.
50       */
51      public MutableFloat() {
52      }
53  
54      /**
55       * Constructs a new MutableFloat with the specified value.
56       *
57       * @param value  The initial value to store.
58       */
59      public MutableFloat(final float value) {
60          this.value = value;
61      }
62  
63      /**
64       * Constructs a new MutableFloat with the specified value.
65       *
66       * @param value  The initial value to store, not null.
67       * @throws NullPointerException Thrown if the object is null.
68       */
69      public MutableFloat(final Number value) {
70          this.value = value.floatValue();
71      }
72  
73      /**
74       * Constructs a new MutableFloat parsing the given string.
75       *
76       * @param value  The string to parse, not null.
77       * @throws NumberFormatException Thrown if the string cannot be parsed into a float, see {@link Float#parseFloat(String)}.
78       * @since 2.5
79       */
80      public MutableFloat(final String value) {
81          this.value = Float.parseFloat(value);
82      }
83  
84      /**
85       * Adds a value to the value of this instance.
86       *
87       * @param operand  The value to add, not null.
88       * @since 2.2
89       */
90      public void add(final float operand) {
91          this.value += operand;
92      }
93  
94      /**
95       * Adds a value to the value of this instance.
96       *
97       * @param operand  The value to add, not null.
98       * @throws NullPointerException Thrown if the object is null.
99       * @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 Thrown 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}.</li>
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}.</li>
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      * Gets this instance's current value, then adds {@code operand}. This method is not thread-safe.
221      *
222      * @param operand The quantity to add, not null.
223      * @return The value associated with this instance immediately before the operand was added.
224      * @since 3.5
225      */
226     public float getAndAdd(final float operand) {
227         final float last = value;
228         this.value += operand;
229         return last;
230     }
231 
232     /**
233      * Gets this instance's current value, then adds {@code operand}. This method is not thread-safe.
234      *
235      * @param operand The quantity to add, not null.
236      * @throws NullPointerException Thrown if {@code operand} is null.
237      * @return The value associated with this instance immediately before the operand was added.
238      * @since 3.5
239      */
240     public float getAndAdd(final Number operand) {
241         final float last = value;
242         this.value += operand.floatValue();
243         return last;
244     }
245 
246     /**
247      * Gets this instance's current value, then decrements it by 1. This method is not thread-safe.
248      *
249      * @return The value associated with the instance before it was decremented.
250      * @since 3.5
251      */
252     public float getAndDecrement() {
253         final float last = value;
254         value--;
255         return last;
256     }
257 
258     /**
259      * Gets this instance's current value, then increments it by 1. This method is not thread-safe.
260      *
261      * @return The value associated with the instance before it was incremented.
262      * @since 3.5
263      */
264     public float getAndIncrement() {
265         final float last = value;
266         value++;
267         return last;
268     }
269 
270     /**
271      * Gets the value as a Float instance.
272      *
273      * @return The value as a Float, never null.
274      * @deprecated Use {@link #get()}.
275      */
276     @Deprecated
277     @Override
278     public Float getValue() {
279         return Float.valueOf(this.value);
280     }
281 
282     /**
283      * Returns a suitable hash code for this mutable.
284      *
285      * @return A suitable hash code.
286      */
287     @Override
288     public int hashCode() {
289         return Float.floatToIntBits(value);
290     }
291 
292     /**
293      * Increments the value.
294      *
295      * @since 2.2
296      */
297     public void increment() {
298         value++;
299     }
300 
301     /**
302      * Increments this instance's value by 1; this method returns the value associated with the instance
303      * immediately after the increment operation. This method is not thread safe.
304      *
305      * @return The value associated with the instance after it is incremented.
306      * @since 3.5
307      */
308     public float incrementAndGet() {
309         value++;
310         return value;
311     }
312 
313     // shortValue and byteValue rely on Number implementation
314     /**
315      * Returns the value of this MutableFloat as an int.
316      *
317      * @return The numeric value represented by this object after conversion to type int.
318      */
319     @Override
320     public int intValue() {
321         return (int) value;
322     }
323 
324     /**
325      * Tests whether the float value is infinite.
326      *
327      * @return true if infinite
328      */
329     public boolean isInfinite() {
330         return Float.isInfinite(value);
331     }
332 
333     /**
334      * Tests whether the float value is the special NaN value.
335      *
336      * @return true if NaN.
337      */
338     public boolean isNaN() {
339         return Float.isNaN(value);
340     }
341 
342     /**
343      * Returns the value of this MutableFloat as a long.
344      *
345      * @return The numeric value represented by this object after conversion to type long.
346      */
347     @Override
348     public long longValue() {
349         return (long) value;
350     }
351 
352     /**
353      * Sets the value.
354      *
355      * @param value  The value to set.
356      */
357     public void setValue(final float value) {
358         this.value = value;
359     }
360 
361     /**
362      * Sets the value from any Number instance.
363      *
364      * @param value  The value to set, not null.
365      * @throws NullPointerException Thrown if the object is null.
366      */
367     @Override
368     public void setValue(final Number value) {
369         this.value = value.floatValue();
370     }
371 
372     /**
373      * Subtracts a value from the value of this instance.
374      *
375      * @param operand  The value to subtract.
376      * @since 2.2
377      */
378     public void subtract(final float operand) {
379         this.value -= operand;
380     }
381 
382     /**
383      * Subtracts a value from the value of this instance.
384      *
385      * @param operand  The value to subtract, not null.
386      * @throws NullPointerException Thrown if the object is null.
387      * @since 2.2
388      */
389     public void subtract(final Number operand) {
390         this.value -= operand.floatValue();
391     }
392 
393     /**
394      * Gets this mutable as an instance of Float.
395      *
396      * @return A Float instance containing the value from this mutable, never null.
397      */
398     public Float toFloat() {
399         return Float.valueOf(floatValue());
400     }
401 
402     /**
403      * Returns the String value of this mutable.
404      *
405      * @return The mutable value as a string.
406      */
407     @Override
408     public String toString() {
409         return String.valueOf(value);
410     }
411 
412 }