001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3.mutable; 018 019import java.util.concurrent.atomic.DoubleAccumulator; 020import java.util.concurrent.atomic.DoubleAdder; 021 022/** 023 * A mutable {@code double} wrapper. 024 * <p> 025 * This class was created before the introduction of the {@link java.util.concurrent.atomic} package and the {@link DoubleAccumulator} class. 026 * </p> 027 * <p> 028 * Note that as MutableDouble does not extend Double, it is not treated by String.format as a Double parameter. 029 * </p> 030 * 031 * @see Double 032 * @see DoubleAccumulator 033 * @see DoubleAdder 034 * @since 2.1 035 */ 036public class MutableDouble extends Number implements Comparable<MutableDouble>, Mutable<Number> { 037 038 /** 039 * Required for serialization support. 040 * 041 * @see java.io.Serializable 042 */ 043 private static final long serialVersionUID = 1587163916L; 044 045 /** The mutable value. */ 046 private double value; 047 048 /** 049 * Constructs a new MutableDouble with the default value of zero. 050 */ 051 public MutableDouble() { 052 } 053 054 /** 055 * Constructs a new MutableDouble with the specified value. 056 * 057 * @param value The initial value to store. 058 */ 059 public MutableDouble(final double value) { 060 this.value = value; 061 } 062 063 /** 064 * Constructs a new MutableDouble with the specified value. 065 * 066 * @param value The initial value to store, not null. 067 * @throws NullPointerException Thrown if the object is null. 068 */ 069 public MutableDouble(final Number value) { 070 this.value = value.doubleValue(); 071 } 072 073 /** 074 * Constructs a new MutableDouble parsing the given string. 075 * 076 * @param value The string to parse, not null. 077 * @throws NumberFormatException Thrown if the string cannot be parsed into a double, see {@link Double#parseDouble(String)}. 078 * @since 2.5 079 */ 080 public MutableDouble(final String value) { 081 this.value = Double.parseDouble(value); 082 } 083 084 /** 085 * Adds a value to the value of this instance. 086 * 087 * @param operand The value to add. 088 * @since 2.2 089 */ 090 public void add(final double operand) { 091 this.value += operand; 092 } 093 094 /** 095 * Adds a value to the value of this instance. 096 * 097 * @param operand The value to add, not null. 098 * @throws NullPointerException Thrown if the object is null. 099 * @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 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 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}.</li> 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.</li> 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 * Gets this instance's current value, then adds {@code operand}. This method is not thread-safe. 217 * 218 * @param operand The quantity to add, not null. 219 * @return The value associated with this instance immediately before the operand was added. 220 * @since 3.5 221 */ 222 public double getAndAdd(final double operand) { 223 final double last = value; 224 this.value += operand; 225 return last; 226 } 227 228 /** 229 * Gets this instance's current value, then adds {@code operand}. This method is not thread-safe. 230 * 231 * @param operand The quantity to add, not null. 232 * @throws NullPointerException Thrown if {@code operand} is null. 233 * @return The value associated with this instance immediately before the operand was added. 234 * @since 3.5 235 */ 236 public double getAndAdd(final Number operand) { 237 final double last = value; 238 this.value += operand.doubleValue(); 239 return last; 240 } 241 242 /** 243 * Gets this instance's current value, then decrements it by 1. This method is not thread-safe. 244 * 245 * @return The value associated with the instance before it was decremented. 246 * @since 3.5 247 */ 248 public double getAndDecrement() { 249 final double last = value; 250 value--; 251 return last; 252 } 253 254 /** 255 * Gets this instance's current value, then increments it by 1. 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 * Tests 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 * Tests 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 Thrown 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 Thrown 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}