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 }