    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     *      http://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     */
    017    package org.apache.commons.lang.mutable;
    018
    019    import org.apache.commons.lang.math.NumberUtils;
    020
    021    /**
    022     * A mutable <code>double</code> wrapper.
    023     *
    024     * @see Double
    025     * @since 2.1
    026     * @author Apache Software Foundation
    027     * @version $Id: MutableDouble.java 905707 2010-02-02 16:59:59Z niallp $
    028     */
    029    public class MutableDouble extends Number implements Comparable, Mutable {
    030
    031        /**
    032         * Required for serialization support.
    033         *
    034         * @see java.io.Serializable
    035         */
    036        private static final long serialVersionUID = 1587163916L;
    037
    038        /** The mutable value. */
    039        private double value;
    040
    041        /**
    042         * Constructs a new MutableDouble with the default value of zero.
    043         */
    044        public MutableDouble() {
    045            super();
    046        }
    047
    048        /**
    049         * Constructs a new MutableDouble with the specified value.
    050         *
    051         * @param value  the initial value to store
    052         */
    053        public MutableDouble(double value) {
    054            super();
    055            this.value = value;
    056        }
    057
    058        /**
    059         * Constructs a new MutableDouble with the specified value.
    060         *
    061         * @param value  the initial value to store, not null
    062         * @throws NullPointerException if the object is null
    063         */
    064        public MutableDouble(Number value) {
    065            super();
    066            this.value = value.doubleValue();
    067        }
    068
    069        /**
    070         * Constructs a new MutableDouble parsing the given string.
    071         *
    072         * @param value  the string to parse, not null
    073         * @throws NumberFormatException if the string cannot be parsed into a double
    074         * @since 2.5
    075         */
    076        public MutableDouble(String value) throws NumberFormatException {
    077            super();
    078            this.value = Double.parseDouble(value);
    079        }
    080
    081        //-----------------------------------------------------------------------
    082        /**
    083         * Gets the value as a Double instance.
    084         *
    085         * @return the value as a Double, never null
    086         */
    087        public Object getValue() {
    088            return new Double(this.value);
    089        }
    090
    091        /**
    092         * Sets the value.
    093         *
    094         * @param value  the value to set
    095         */
    096        public void setValue(double value) {
    097            this.value = value;
    098        }
    099
    100        /**
    101         * Sets the value from any Number instance.
    102         *
    103         * @param value  the value to set, not null
    104         * @throws NullPointerException if the object is null
    105         * @throws ClassCastException if the type is not a {@link Number}
    106         */
    107        public void setValue(Object value) {
    108            setValue(((Number) value).doubleValue());
    109        }
    110
    111        //-----------------------------------------------------------------------
    112        /**
    113         * Checks whether the double value is the special NaN value.
    114         *
    115         * @return true if NaN
    116         */
    117        public boolean isNaN() {
    118            return Double.isNaN(value);
    119        }
    120
    121        /**
    122         * Checks whether the double value is infinite.
    123         *
    124         * @return true if infinite
    125         */
    126        public boolean isInfinite() {
    127            return Double.isInfinite(value);
    128        }
    129
    130        //-----------------------------------------------------------------------
    131        /**
    132         * Increments the value.
    133         *
    134         * @since Commons Lang 2.2
    135         */
    136        public void increment() {
    137            value++;
    138        }
    139
    140        /**
    141         * Decrements the value.
    142         *
    143         * @since Commons Lang 2.2
    144         */
    145        public void decrement() {
    146            value--;
    147        }
    148
    149        //-----------------------------------------------------------------------
    150        /**
    151         * Adds a value to the value of this instance.
    152         *
    153         * @param operand  the value to add
    154         * @since Commons Lang 2.2
    155         */
    156        public void add(double operand) {
    157            this.value += operand;
    158        }
    159
    160        /**
    161         * Adds a value to the value of this instance.
    162         *
    163         * @param operand  the value to add, not null
    164         * @throws NullPointerException if the object is null
    165         * @since Commons Lang 2.2
    166         */
    167        public void add(Number operand) {
    168            this.value += operand.doubleValue();
    169        }
    170
    171        /**
    172         * Subtracts a value from the value of this instance.
    173         *
    174         * @param operand  the value to subtract, not null
    175         * @since Commons Lang 2.2
    176         */
    177        public void subtract(double operand) {
    178            this.value -= operand;
    179        }
    180
    181        /**
    182         * Subtracts a value from the value of this instance.
    183         *
    184         * @param operand  the value to subtract, not null
    185         * @throws NullPointerException if the object is null
    186         * @since Commons Lang 2.2
    187         */
    188        public void subtract(Number operand) {
    189            this.value -= operand.doubleValue();
    190        }
    191
    192        //-----------------------------------------------------------------------
    193        // shortValue and bytValue rely on Number implementation
    194        /**
    195         * Returns the value of this MutableDouble as an int.
    196         *
    197         * @return the numeric value represented by this object after conversion to type int.
    198         */
    199        public int intValue() {
    200            return (int) value;
    201        }
    202
    203        /**
    204         * Returns the value of this MutableDouble as a long.
    205         *
    206         * @return the numeric value represented by this object after conversion to type long.
    207         */
    208        public long longValue() {
    209            return (long) value;
    210        }
    211
    212        /**
    213         * Returns the value of this MutableDouble as a float.
    214         *
    215         * @return the numeric value represented by this object after conversion to type float.
    216         */
    217        public float floatValue() {
    218            return (float) value;
    219        }
    220
    221        /**
    222         * Returns the value of this MutableDouble as a double.
    223         *
    224         * @return the numeric value represented by this object after conversion to type double.
    225         */
    226        public double doubleValue() {
    227            return value;
    228        }
    229
    230        //-----------------------------------------------------------------------
    231        /**
    232         * Gets this mutable as an instance of Double.
    233         *
    234         * @return a Double instance containing the value from this mutable, never null
    235         */
    236        public Double toDouble() {
    237            return new Double(doubleValue());
    238        }
    239
    240        //-----------------------------------------------------------------------
    241        /**
    242         * Compares this object against the specified object. The result is <code>true</code> if and only if the argument
    243         * is not <code>null</code> and is a <code>Double</code> object that represents a double that has the identical
    244         * bit pattern to the bit pattern of the double represented by this object. For this purpose, two
    245         * <code>double</code> values are considered to be the same if and only if the method
    246         * {@link Double#doubleToLongBits(double)}returns the same long value when applied to each.
    247         * <p>
    248         * Note that in most cases, for two instances of class <code>Double</code>,<code>d1</code> and <code>d2</code>,
    249         * the value of <code>d1.equals(d2)</code> is <code>true</code> if and only if <blockquote>
    250         *
    251         * <pre>
    252         *   d1.doubleValue()&nbsp;== d2.doubleValue()
    253         * </pre>
    254         *
    255         * </blockquote>
    256         * <p>
    257         * also has the value <code>true</code>. However, there are two exceptions:
    258         * <ul>
    259         * <li>If <code>d1</code> and <code>d2</code> both represent <code>Double.NaN</code>, then the
    260         * <code>equals</code> method returns <code>true</code>, even though <code>Double.NaN==Double.NaN</code> has
    261         * the value <code>false</code>.
    262         * <li>If <code>d1</code> represents <code>+0.0</code> while <code>d2</code> represents <code>-0.0</code>,
    263         * or vice versa, the <code>equal</code> test has the value <code>false</code>, even though
    264         * <code>+0.0==-0.0</code> has the value <code>true</code>. This allows hashtables to operate properly.
    265         * </ul>
    266         *
    267         * @param obj  the object to compare with, null returns false
    268         * @return <code>true</code> if the objects are the same; <code>false</code> otherwise.
    269         */
    270        public boolean equals(Object obj) {
    271            return (obj instanceof MutableDouble)
    272                && (Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value));
    273        }
    274
    275        /**
    276         * Returns a suitable hash code for this mutable.
    277         *
    278         * @return a suitable hash code
    279         */
    280        public int hashCode() {
    281            long bits = Double.doubleToLongBits(value);
    282            return (int) (bits ^ (bits >>> 32));
    283        }
    284
    285        //-----------------------------------------------------------------------
    286        /**
    287         * Compares this mutable to another in ascending order.
    288         *
    289         * @param obj the other mutable to compare to, not null
    290         * @return negative if this is less, zero if equal, positive if greater
    291         * @throws ClassCastException if the argument is not a MutableDouble
    292         */
    293        public int compareTo(Object obj) {
    294            MutableDouble other = (MutableDouble) obj;
    295            double anotherVal = other.value;
    296            return NumberUtils.compare(value, anotherVal);
    297        }
    298
    299        //-----------------------------------------------------------------------
    300        /**
    301         * Returns the String value of this mutable.
    302         *
    303         * @return the mutable value as a string
    304         */
    305        public String toString() {
    306            return String.valueOf(value);
    307        }
    308
    309    }