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    *      http://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
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      */
271     @Override
272     public Double getValue() {
273         return Double.valueOf(this.value);
274     }
275 
276     /**
277      * Returns a suitable hash code for this mutable.
278      *
279      * @return a suitable hash code
280      */
281     @Override
282     public int hashCode() {
283         final long bits = Double.doubleToLongBits(value);
284         return (int) (bits ^ bits >>> 32);
285     }
286 
287     /**
288      * Increments the value.
289      *
290      * @since 2.2
291      */
292     public void increment() {
293         value++;
294     }
295 
296     /**
297      * Increments this instance's value by 1; this method returns the value associated with the instance
298      * immediately after the increment operation. This method is not thread safe.
299      *
300      * @return the value associated with the instance after it is incremented
301      * @since 3.5
302      */
303     public double incrementAndGet() {
304         value++;
305         return value;
306     }
307 
308     // shortValue and byteValue rely on Number implementation
309     /**
310      * Returns the value of this MutableDouble as an int.
311      *
312      * @return the numeric value represented by this object after conversion to type int.
313      */
314     @Override
315     public int intValue() {
316         return (int) value;
317     }
318 
319     /**
320      * Checks whether the double value is infinite.
321      *
322      * @return true if infinite
323      */
324     public boolean isInfinite() {
325         return Double.isInfinite(value);
326     }
327 
328     /**
329      * Checks whether the double value is the special NaN value.
330      *
331      * @return true if NaN
332      */
333     public boolean isNaN() {
334         return Double.isNaN(value);
335     }
336 
337     /**
338      * Returns the value of this MutableDouble as a long.
339      *
340      * @return the numeric value represented by this object after conversion to type long.
341      */
342     @Override
343     public long longValue() {
344         return (long) value;
345     }
346 
347     /**
348      * Sets the value.
349      *
350      * @param value  the value to set
351      */
352     public void setValue(final double value) {
353         this.value = value;
354     }
355 
356     /**
357      * Sets the value from any Number instance.
358      *
359      * @param value  the value to set, not null
360      * @throws NullPointerException if the object is null
361      */
362     @Override
363     public void setValue(final Number value) {
364         this.value = value.doubleValue();
365     }
366 
367     /**
368      * Subtracts a value from the value of this instance.
369      *
370      * @param operand  the value to subtract, not null
371      * @since 2.2
372      */
373     public void subtract(final double operand) {
374         this.value -= operand;
375     }
376 
377     /**
378      * Subtracts a value from the value of this instance.
379      *
380      * @param operand  the value to subtract, not null
381      * @throws NullPointerException if the object is null
382      * @since 2.2
383      */
384     public void subtract(final Number operand) {
385         this.value -= operand.doubleValue();
386     }
387 
388     /**
389      * Gets this mutable as an instance of Double.
390      *
391      * @return a Double instance containing the value from this mutable, never null
392      */
393     public Double toDouble() {
394         return Double.valueOf(doubleValue());
395     }
396 
397     /**
398      * Returns the String value of this mutable.
399      *
400      * @return the mutable value as a string
401      */
402     @Override
403     public String toString() {
404         return String.valueOf(value);
405     }
406 
407 }