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  /**
20   * A mutable {@code double} wrapper.
21   * <p>
22   * Note that as MutableDouble does not extend Double, it is not treated by String.format as a Double parameter.
23   * </p>
24   *
25   * @see Double
26   * @since 2.1
27   */
28  public class MutableDouble extends Number implements Comparable<MutableDouble>, Mutable<Number> {
29  
30      /**
31       * Required for serialization support.
32       *
33       * @see java.io.Serializable
34       */
35      private static final long serialVersionUID = 1587163916L;
36  
37      /** The mutable value. */
38      private double value;
39  
40      /**
41       * Constructs a new MutableDouble with the default value of zero.
42       */
43      public MutableDouble() {
44      }
45  
46      /**
47       * Constructs a new MutableDouble with the specified value.
48       *
49       * @param value  the initial value to store
50       */
51      public MutableDouble(final double value) {
52          this.value = value;
53      }
54  
55      /**
56       * Constructs a new MutableDouble with the specified value.
57       *
58       * @param value  the initial value to store, not null
59       * @throws NullPointerException if the object is null
60       */
61      public MutableDouble(final Number value) {
62          this.value = value.doubleValue();
63      }
64  
65      /**
66       * Constructs a new MutableDouble parsing the given string.
67       *
68       * @param value  the string to parse, not null
69       * @throws NumberFormatException if the string cannot be parsed into a double, see {@link Double#parseDouble(String)}.
70       * @since 2.5
71       */
72      public MutableDouble(final String value) {
73          this.value = Double.parseDouble(value);
74      }
75  
76      /**
77       * Adds a value to the value of this instance.
78       *
79       * @param operand  the value to add
80       * @since 2.2
81       */
82      public void add(final double operand) {
83          this.value += operand;
84      }
85  
86      /**
87       * Adds a value to the value of this instance.
88       *
89       * @param operand  the value to add, not null
90       * @throws NullPointerException if the object is null
91       * @since 2.2
92       */
93      public void add(final Number operand) {
94          this.value += operand.doubleValue();
95      }
96  
97      /**
98       * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
99       * immediately after the addition operation. This method is not thread safe.
100      *
101      * @param operand the quantity to add, not null
102      * @return the value associated with this instance after adding the operand
103      * @since 3.5
104      */
105     public double addAndGet(final double operand) {
106         this.value += operand;
107         return value;
108     }
109 
110     /**
111      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
112      * immediately after the addition operation. This method is not thread safe.
113      *
114      * @param operand the quantity to add, not null
115      * @throws NullPointerException if {@code operand} is null
116      * @return the value associated with this instance after adding the operand
117      * @since 3.5
118      */
119     public double addAndGet(final Number operand) {
120         this.value += operand.doubleValue();
121         return value;
122     }
123 
124     /**
125      * Compares this mutable to another in ascending order.
126      *
127      * @param other  the other mutable to compare to, not null
128      * @return negative if this is less, zero if equal, positive if greater
129      */
130     @Override
131     public int compareTo(final MutableDouble other) {
132         return Double.compare(this.value, other.value);
133     }
134 
135     /**
136      * Decrements the value.
137      *
138      * @since 2.2
139      */
140     public void decrement() {
141         value--;
142     }
143 
144     /**
145      * Decrements this instance's value by 1; this method returns the value associated with the instance
146      * immediately after the decrement operation. This method is not thread safe.
147      *
148      * @return the value associated with the instance after it is decremented
149      * @since 3.5
150      */
151     public double decrementAndGet() {
152         value--;
153         return value;
154     }
155 
156     /**
157      * Returns the value of this MutableDouble as a double.
158      *
159      * @return the numeric value represented by this object after conversion to type double.
160      */
161     @Override
162     public double doubleValue() {
163         return value;
164     }
165 
166     /**
167      * Compares this object against the specified object. The result is {@code true} if and only if the argument
168      * is not {@code null} and is a {@link Double} object that represents a double that has the identical
169      * bit pattern to the bit pattern of the double represented by this object. For this purpose, two
170      * {@code double} values are considered to be the same if and only if the method
171      * {@link Double#doubleToLongBits(double)}returns the same long value when applied to each.
172      * <p>
173      * Note that in most cases, for two instances of class {@link Double},{@code d1} and {@code d2},
174      * the value of {@code d1.equals(d2)} is {@code true} if and only if <blockquote>
175      *
176      * <pre>
177      *   d1.doubleValue()&nbsp;== d2.doubleValue()
178      * </pre>
179      *
180      * </blockquote>
181      * <p>
182      * also has the value {@code true}. However, there are two exceptions:
183      * <ul>
184      * <li>If {@code d1} and {@code d2} both represent {@code Double.NaN}, then the
185      * {@code equals} method returns {@code true}, even though {@code Double.NaN == Double.NaN} has
186      * the value {@code false}.
187      * <li>If {@code d1} represents {@code +0.0} while {@code d2} represents {@code -0.0},
188      * or vice versa, the {@code equal} test has the value {@code false}, even though
189      * {@code +0.0 == -0.0} has the value {@code true}. This allows hashtables to operate properly.
190      * </ul>
191      *
192      * @param obj  the object to compare with, null returns false
193      * @return {@code true} if the objects are the same; {@code false} otherwise.
194      */
195     @Override
196     public boolean equals(final Object obj) {
197         return obj instanceof MutableDouble
198             && Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value);
199     }
200 
201     /**
202      * Returns the value of this MutableDouble as a float.
203      *
204      * @return the numeric value represented by this object after conversion to type float.
205      */
206     @Override
207     public float floatValue() {
208         return (float) value;
209     }
210 
211     /**
212      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
213      * immediately prior to the addition operation. This method is not thread safe.
214      *
215      * @param operand the quantity to add, not null
216      * @return the value associated with this instance immediately before the operand was added
217      * @since 3.5
218      */
219     public double getAndAdd(final double operand) {
220         final double last = value;
221         this.value += operand;
222         return last;
223     }
224 
225     /**
226      * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
227      * immediately prior to the addition operation. This method is not thread safe.
228      *
229      * @param operand the quantity to add, not null
230      * @throws NullPointerException if {@code operand} is null
231      * @return the value associated with this instance immediately before the operand was added
232      * @since 3.5
233      */
234     public double getAndAdd(final Number operand) {
235         final double last = value;
236         this.value += operand.doubleValue();
237         return last;
238     }
239 
240     /**
241      * Decrements this instance's value by 1; this method returns the value associated with the instance
242      * immediately prior to the decrement operation. This method is not thread safe.
243      *
244      * @return the value associated with the instance before it was decremented
245      * @since 3.5
246      */
247     public double getAndDecrement() {
248         final double last = value;
249         value--;
250         return last;
251     }
252 
253     /**
254      * Increments this instance's value by 1; this method returns the value associated with the instance
255      * immediately prior to the increment operation. This method is not thread safe.
256      *
257      * @return the value associated with the instance before it was incremented
258      * @since 3.5
259      */
260     public double getAndIncrement() {
261         final double last = value;
262         value++;
263         return last;
264     }
265 
266     /**
267      * Gets the value as a Double instance.
268      *
269      * @return the value as a Double, never null.
270      * @deprecated Use {@link #get()}.
271      */
272     @Deprecated
273     @Override
274     public Double getValue() {
275         return Double.valueOf(this.value);
276     }
277 
278     /**
279      * Returns a suitable hash code for this mutable.
280      *
281      * @return a suitable hash code
282      */
283     @Override
284     public int hashCode() {
285         final long bits = Double.doubleToLongBits(value);
286         return (int) (bits ^ bits >>> 32);
287     }
288 
289     /**
290      * Increments the value.
291      *
292      * @since 2.2
293      */
294     public void increment() {
295         value++;
296     }
297 
298     /**
299      * Increments this instance's value by 1; this method returns the value associated with the instance
300      * immediately after the increment operation. This method is not thread safe.
301      *
302      * @return the value associated with the instance after it is incremented
303      * @since 3.5
304      */
305     public double incrementAndGet() {
306         value++;
307         return value;
308     }
309 
310     // shortValue and byteValue rely on Number implementation
311     /**
312      * Returns the value of this MutableDouble as an int.
313      *
314      * @return the numeric value represented by this object after conversion to type int.
315      */
316     @Override
317     public int intValue() {
318         return (int) value;
319     }
320 
321     /**
322      * Checks whether the double value is infinite.
323      *
324      * @return true if infinite
325      */
326     public boolean isInfinite() {
327         return Double.isInfinite(value);
328     }
329 
330     /**
331      * Checks whether the double value is the special NaN value.
332      *
333      * @return true if NaN
334      */
335     public boolean isNaN() {
336         return Double.isNaN(value);
337     }
338 
339     /**
340      * Returns the value of this MutableDouble as a long.
341      *
342      * @return the numeric value represented by this object after conversion to type long.
343      */
344     @Override
345     public long longValue() {
346         return (long) value;
347     }
348 
349     /**
350      * Sets the value.
351      *
352      * @param value  the value to set
353      */
354     public void setValue(final double value) {
355         this.value = value;
356     }
357 
358     /**
359      * Sets the value from any Number instance.
360      *
361      * @param value  the value to set, not null
362      * @throws NullPointerException if the object is null
363      */
364     @Override
365     public void setValue(final Number value) {
366         this.value = value.doubleValue();
367     }
368 
369     /**
370      * Subtracts a value from the value of this instance.
371      *
372      * @param operand  the value to subtract, not null
373      * @since 2.2
374      */
375     public void subtract(final double operand) {
376         this.value -= operand;
377     }
378 
379     /**
380      * Subtracts a value from the value of this instance.
381      *
382      * @param operand  the value to subtract, not null
383      * @throws NullPointerException if the object is null
384      * @since 2.2
385      */
386     public void subtract(final Number operand) {
387         this.value -= operand.doubleValue();
388     }
389 
390     /**
391      * Gets this mutable as an instance of Double.
392      *
393      * @return a Double instance containing the value from this mutable, never null
394      */
395     public Double toDouble() {
396         return Double.valueOf(doubleValue());
397     }
398 
399     /**
400      * Returns the String value of this mutable.
401      *
402      * @return the mutable value as a string
403      */
404     @Override
405     public String toString() {
406         return String.valueOf(value);
407     }
408 
409 }