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 double} 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 MutableDouble does not extend Double, it is not treated by String.format as a Double parameter.
29   * </p>
30   *
31   * @see Double
32   * @see DoubleAccumulator
33   * @see DoubleAdder
34   * @since 2.1
35   */
36  public class MutableDouble extends Number implements Comparable<MutableDouble>, Mutable<Number> {
37  
38      /**
39       * Required for serialization support.
40       *
41       * @see java.io.Serializable
42       */
43      private static final long serialVersionUID = 1587163916L;
44  
45      /** The mutable value. */
46      private double value;
47  
48      /**
49       * Constructs a new MutableDouble with the default value of zero.
50       */
51      public MutableDouble() {
52      }
53  
54      /**
55       * Constructs a new MutableDouble with the specified value.
56       *
57       * @param value  the initial value to store.
58       */
59      public MutableDouble(final double value) {
60          this.value = value;
61      }
62  
63      /**
64       * Constructs a new MutableDouble 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 MutableDouble(final Number value) {
70          this.value = value.doubleValue();
71      }
72  
73      /**
74       * Constructs a new MutableDouble 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 double, see {@link Double#parseDouble(String)}.
78       * @since 2.5
79       */
80      public MutableDouble(final String value) {
81          this.value = Double.parseDouble(value);
82      }
83  
84      /**
85       * Adds a value to the value of this instance.
86       *
87       * @param operand  the value to add.
88       * @since 2.2
89       */
90      public void add(final double 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.doubleValue();
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 double addAndGet(final double 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 double addAndGet(final Number operand) {
128         this.value += operand.doubleValue();
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 MutableDouble other) {
140         return Double.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 double decrementAndGet() {
160         value--;
161         return value;
162     }
163 
164     /**
165      * Returns the value of this MutableDouble 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 the specified object. The result is {@code true} if and only if the argument is not {@code null} and is a {@link Double}
176      * object that represents a double that has the identical bit pattern to the bit pattern of the double represented by this object. For this purpose, two
177      * {@code double} values are considered to be the same if and only if the method {@link Double#doubleToLongBits(double)}returns the same long value when
178      * applied to each.
179      * <p>
180      * Note that in most cases, for two instances of class {@link Double},{@code d1} and {@code d2}, the value of {@code d1.equals(d2)} is {@code true} if and
181      * only if:
182      * </p>
183      * <pre>
184      * d1.doubleValue() == d2.doubleValue()
185      * </pre>
186      * <p>
187      * also has the value {@code true}. However, there are two exceptions:
188      * </p>
189      * <ul>
190      * <li>If {@code d1} and {@code d2} both represent {@code Double.NaN}, then the {@code equals} method returns {@code true}, even though
191      * {@code Double.NaN == Double.NaN} has the value {@code false}.
192      * <li>If {@code d1} represents {@code +0.0} while {@code d2} represents {@code -0.0}, or vice versa, the {@code equal} test has the value {@code false},
193      * even though {@code +0.0 == -0.0} has the value {@code true}. This allows hashtables to operate properly.
194      * </ul>
195      *
196      * @param obj the object to compare with, null returns false.
197      * @return {@code true} if the objects are the same; {@code false} otherwise.
198      */
199     @Override
200     public boolean equals(final Object obj) {
201         return obj instanceof MutableDouble
202             && Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value);
203     }
204 
205     /**
206      * Returns the value of this MutableDouble as a float.
207      *
208      * @return the numeric value represented by this object after conversion to type float.
209      */
210     @Override
211     public float floatValue() {
212         return (float) value;
213     }
214 
215     /**
216      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
217      * immediately prior to the addition operation. This method is not thread safe.
218      *
219      * @param operand the quantity to add, not null.
220      * @return the value associated with this instance immediately before the operand was added.
221      * @since 3.5
222      */
223     public double getAndAdd(final double operand) {
224         final double last = value;
225         this.value += operand;
226         return last;
227     }
228 
229     /**
230      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
231      * immediately prior to the addition operation. This method is not thread safe.
232      *
233      * @param operand the quantity to add, not null.
234      * @throws NullPointerException if {@code operand} is null.
235      * @return the value associated with this instance immediately before the operand was added.
236      * @since 3.5
237      */
238     public double getAndAdd(final Number operand) {
239         final double last = value;
240         this.value += operand.doubleValue();
241         return last;
242     }
243 
244     /**
245      * Decrements this instance's value by 1; this method returns the value associated with the instance
246      * immediately prior to the decrement operation. This method is not thread safe.
247      *
248      * @return the value associated with the instance before it was decremented.
249      * @since 3.5
250      */
251     public double getAndDecrement() {
252         final double last = value;
253         value--;
254         return last;
255     }
256 
257     /**
258      * Increments this instance's value by 1; this method returns the value associated with the instance
259      * immediately prior to the increment operation. 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 double getAndIncrement() {
265         final double last = value;
266         value++;
267         return last;
268     }
269 
270     /**
271      * Gets the value as a Double instance.
272      *
273      * @return the value as a Double, never null.
274      * @deprecated Use {@link #get()}.
275      */
276     @Deprecated
277     @Override
278     public Double getValue() {
279         return Double.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         final long bits = Double.doubleToLongBits(value);
290         return (int) (bits ^ bits >>> 32);
291     }
292 
293     /**
294      * Increments the value.
295      *
296      * @since 2.2
297      */
298     public void increment() {
299         value++;
300     }
301 
302     /**
303      * Increments this instance's value by 1; this method returns the value associated with the instance
304      * immediately after the increment operation. This method is not thread safe.
305      *
306      * @return the value associated with the instance after it is incremented.
307      * @since 3.5
308      */
309     public double incrementAndGet() {
310         value++;
311         return value;
312     }
313 
314     // shortValue and byteValue rely on Number implementation
315     /**
316      * Returns the value of this MutableDouble as an int.
317      *
318      * @return the numeric value represented by this object after conversion to type int.
319      */
320     @Override
321     public int intValue() {
322         return (int) value;
323     }
324 
325     /**
326      * Checks whether the double value is infinite.
327      *
328      * @return true if infinite.
329      */
330     public boolean isInfinite() {
331         return Double.isInfinite(value);
332     }
333 
334     /**
335      * Checks whether the double value is the special NaN value.
336      *
337      * @return true if NaN.
338      */
339     public boolean isNaN() {
340         return Double.isNaN(value);
341     }
342 
343     /**
344      * Returns the value of this MutableDouble as a long.
345      *
346      * @return the numeric value represented by this object after conversion to type long.
347      */
348     @Override
349     public long longValue() {
350         return (long) value;
351     }
352 
353     /**
354      * Sets the value.
355      *
356      * @param value  the value to set.
357      */
358     public void setValue(final double value) {
359         this.value = value;
360     }
361 
362     /**
363      * Sets the value from any Number instance.
364      *
365      * @param value  the value to set, not null.
366      * @throws NullPointerException if the object is null.
367      */
368     @Override
369     public void setValue(final Number value) {
370         this.value = value.doubleValue();
371     }
372 
373     /**
374      * Subtracts a value from the value of this instance.
375      *
376      * @param operand  the value to subtract, not null.
377      * @since 2.2
378      */
379     public void subtract(final double operand) {
380         this.value -= operand;
381     }
382 
383     /**
384      * Subtracts a value from the value of this instance.
385      *
386      * @param operand  the value to subtract, not null.
387      * @throws NullPointerException if the object is null.
388      * @since 2.2
389      */
390     public void subtract(final Number operand) {
391         this.value -= operand.doubleValue();
392     }
393 
394     /**
395      * Gets this mutable as an instance of Double.
396      *
397      * @return a Double instance containing the value from this mutable, never null.
398      */
399     public Double toDouble() {
400         return Double.valueOf(doubleValue());
401     }
402 
403     /**
404      * Returns the String value of this mutable.
405      *
406      * @return the mutable value as a string.
407      */
408     @Override
409     public String toString() {
410         return String.valueOf(value);
411     }
412 
413 }