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 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 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 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 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 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}.
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}.
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      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
221      * immediately prior to the addition operation. This method is not thread safe.
222      *
223      * @param operand the quantity to add, not null.
224      * @return the value associated with this instance immediately before the operand was added.
225      * @since 3.5
226      */
227     public float getAndAdd(final float operand) {
228         final float last = value;
229         this.value += operand;
230         return last;
231     }
232 
233     /**
234      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
235      * immediately prior to the addition operation. This method is not thread safe.
236      *
237      * @param operand the quantity to add, not null.
238      * @throws NullPointerException if {@code operand} is null.
239      * @return the value associated with this instance immediately before the operand was added.
240      * @since 3.5
241      */
242     public float getAndAdd(final Number operand) {
243         final float last = value;
244         this.value += operand.floatValue();
245         return last;
246     }
247 
248     /**
249      * Decrements this instance's value by 1; this method returns the value associated with the instance
250      * immediately prior to the decrement operation. This method is not thread safe.
251      *
252      * @return the value associated with the instance before it was decremented.
253      * @since 3.5
254      */
255     public float getAndDecrement() {
256         final float last = value;
257         value--;
258         return last;
259     }
260 
261     /**
262      * Increments this instance's value by 1; this method returns the value associated with the instance
263      * immediately prior to the increment operation. This method is not thread safe.
264      *
265      * @return the value associated with the instance before it was incremented.
266      * @since 3.5
267      */
268     public float getAndIncrement() {
269         final float last = value;
270         value++;
271         return last;
272     }
273 
274     /**
275      * Gets the value as a Float instance.
276      *
277      * @return the value as a Float, never null.
278      * @deprecated Use {@link #get()}.
279      */
280     @Deprecated
281     @Override
282     public Float getValue() {
283         return Float.valueOf(this.value);
284     }
285 
286     /**
287      * Returns a suitable hash code for this mutable.
288      *
289      * @return a suitable hash code.
290      */
291     @Override
292     public int hashCode() {
293         return Float.floatToIntBits(value);
294     }
295 
296     /**
297      * Increments the value.
298      *
299      * @since 2.2
300      */
301     public void increment() {
302         value++;
303     }
304 
305     /**
306      * Increments this instance's value by 1; this method returns the value associated with the instance
307      * immediately after the increment operation. This method is not thread safe.
308      *
309      * @return the value associated with the instance after it is incremented.
310      * @since 3.5
311      */
312     public float incrementAndGet() {
313         value++;
314         return value;
315     }
316 
317     // shortValue and byteValue rely on Number implementation
318     /**
319      * Returns the value of this MutableFloat as an int.
320      *
321      * @return the numeric value represented by this object after conversion to type int.
322      */
323     @Override
324     public int intValue() {
325         return (int) value;
326     }
327 
328     /**
329      * Checks whether the float value is infinite.
330      *
331      * @return true if infinite
332      */
333     public boolean isInfinite() {
334         return Float.isInfinite(value);
335     }
336 
337     /**
338      * Checks whether the float value is the special NaN value.
339      *
340      * @return true if NaN.
341      */
342     public boolean isNaN() {
343         return Float.isNaN(value);
344     }
345 
346     /**
347      * Returns the value of this MutableFloat as a long.
348      *
349      * @return the numeric value represented by this object after conversion to type long.
350      */
351     @Override
352     public long longValue() {
353         return (long) value;
354     }
355 
356     /**
357      * Sets the value.
358      *
359      * @param value  the value to set.
360      */
361     public void setValue(final float value) {
362         this.value = value;
363     }
364 
365     /**
366      * Sets the value from any Number instance.
367      *
368      * @param value  the value to set, not null.
369      * @throws NullPointerException if the object is null.
370      */
371     @Override
372     public void setValue(final Number value) {
373         this.value = value.floatValue();
374     }
375 
376     /**
377      * Subtracts a value from the value of this instance.
378      *
379      * @param operand  the value to subtract.
380      * @since 2.2
381      */
382     public void subtract(final float operand) {
383         this.value -= operand;
384     }
385 
386     /**
387      * Subtracts a value from the value of this instance.
388      *
389      * @param operand  the value to subtract, not null.
390      * @throws NullPointerException if the object is null.
391      * @since 2.2
392      */
393     public void subtract(final Number operand) {
394         this.value -= operand.floatValue();
395     }
396 
397     /**
398      * Gets this mutable as an instance of Float.
399      *
400      * @return a Float instance containing the value from this mutable, never null.
401      */
402     public Float toFloat() {
403         return Float.valueOf(floatValue());
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 }