    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 */
    017package org.apache.commons.lang3.mutable;
    018
    019import org.apache.commons.lang3.math.NumberUtils;
    020
    021/**
    022 * A mutable {@code long} wrapper.
    023 * <p>
    024 * Note that as MutableLong does not extend Long, it is not treated by String.format as a Long parameter.
    025 * </p>
    026 *
    027 * @see Long
    028 * @since 2.1
    029 */
    030public class MutableLong extends Number implements Comparable<MutableLong>, Mutable<Number> {
    031
    032    /**
    033     * Required for serialization support.
    034     *
    035     * @see java.io.Serializable
    036     */
    037    private static final long serialVersionUID = 62986528375L;
    038
    039    /** The mutable value. */
    040    private long value;
    041
    042    /**
    043     * Constructs a new MutableLong with the default value of zero.
    044     */
    045    public MutableLong() {
    046    }
    047
    048    /**
    049     * Constructs a new MutableLong with the specified value.
    050     *
    051     * @param value  the initial value to store
    052     */
    053    public MutableLong(final long value) {
    054        this.value = value;
    055    }
    056
    057    /**
    058     * Constructs a new MutableLong with the specified value.
    059     *
    060     * @param value  the initial value to store, not null
    061     * @throws NullPointerException if the object is null
    062     */
    063    public MutableLong(final Number value) {
    064        this.value = value.longValue();
    065    }
    066
    067    /**
    068     * Constructs a new MutableLong parsing the given string.
    069     *
    070     * @param value  the string to parse, not null
    071     * @throws NumberFormatException if the string cannot be parsed into a long
    072     * @since 2.5
    073     */
    074    public MutableLong(final String value) {
    075        this.value = Long.parseLong(value);
    076    }
    077
    078    /**
    079     * Adds a value to the value of this instance.
    080     *
    081     * @param operand  the value to add, not null
    082     * @since 2.2
    083     */
    084    public void add(final long operand) {
    085        this.value += operand;
    086    }
    087
    088    /**
    089     * Adds a value to the value of this instance.
    090     *
    091     * @param operand  the value to add, not null
    092     * @throws NullPointerException if the object is null
    093     * @since 2.2
    094     */
    095    public void add(final Number operand) {
    096        this.value += operand.longValue();
    097    }
    098
    099    /**
    100     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    101     * immediately after the addition operation. This method is not thread safe.
    102     *
    103     * @param operand the quantity to add, not null
    104     * @return the value associated with this instance after adding the operand
    105     * @since 3.5
    106     */
    107    public long addAndGet(final long operand) {
    108        this.value += operand;
    109        return value;
    110    }
    111
    112    /**
    113     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    114     * immediately after the addition operation. This method is not thread safe.
    115     *
    116     * @param operand the quantity to add, not null
    117     * @throws NullPointerException if {@code operand} is null
    118     * @return the value associated with this instance after adding the operand
    119     * @since 3.5
    120     */
    121    public long addAndGet(final Number operand) {
    122        this.value += operand.longValue();
    123        return value;
    124    }
    125
    126    /**
    127     * Compares this mutable to another in ascending order.
    128     *
    129     * @param other  the other mutable to compare to, not null
    130     * @return negative if this is less, zero if equal, positive if greater
    131     */
    132    @Override
    133    public int compareTo(final MutableLong other) {
    134        return NumberUtils.compare(this.value, other.value);
    135    }
    136
    137    /**
    138     * Decrements the value.
    139     *
    140     * @since 2.2
    141     */
    142    public void decrement() {
    143        value--;
    144    }
    145
    146    /**
    147     * Decrements this instance's value by 1; this method returns the value associated with the instance
    148     * immediately after the decrement operation. This method is not thread safe.
    149     *
    150     * @return the value associated with the instance after it is decremented
    151     * @since 3.5
    152     */
    153    public long decrementAndGet() {
    154        value--;
    155        return value;
    156    }
    157
    158    /**
    159     * Returns the value of this MutableLong as a double.
    160     *
    161     * @return the numeric value represented by this object after conversion to type double.
    162     */
    163    @Override
    164    public double doubleValue() {
    165        return value;
    166    }
    167
    168    /**
    169     * Compares this object to the specified object. The result is {@code true} if and only if the argument
    170     * is not {@code null} and is a {@link MutableLong} object that contains the same {@code long}
    171     * value as this object.
    172     *
    173     * @param obj  the object to compare with, null returns false
    174     * @return {@code true} if the objects are the same; {@code false} otherwise.
    175     */
    176    @Override
    177    public boolean equals(final Object obj) {
    178        if (obj instanceof MutableLong) {
    179            return value == ((MutableLong) obj).longValue();
    180        }
    181        return false;
    182    }
    183
    184    /**
    185     * Returns the value of this MutableLong as a float.
    186     *
    187     * @return the numeric value represented by this object after conversion to type float.
    188     */
    189    @Override
    190    public float floatValue() {
    191        return value;
    192    }
    193
    194    /**
    195     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    196     * immediately prior to the addition operation. This method is not thread safe.
    197     *
    198     * @param operand the quantity to add, not null
    199     * @return the value associated with this instance immediately before the operand was added
    200     * @since 3.5
    201     */
    202    public long getAndAdd(final long operand) {
    203        final long last = value;
    204        this.value += operand;
    205        return last;
    206    }
    207
    208    /**
    209     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
    210     * immediately prior to the addition operation. This method is not thread safe.
    211     *
    212     * @param operand the quantity to add, not null
    213     * @throws NullPointerException if {@code operand} is null
    214     * @return the value associated with this instance immediately before the operand was added
    215     * @since 3.5
    216     */
    217    public long getAndAdd(final Number operand) {
    218        final long last = value;
    219        this.value += operand.longValue();
    220        return last;
    221    }
    222
    223    /**
    224     * Decrements this instance's value by 1; this method returns the value associated with the instance
    225     * immediately prior to the decrement operation. This method is not thread safe.
    226     *
    227     * @return the value associated with the instance before it was decremented
    228     * @since 3.5
    229     */
    230    public long getAndDecrement() {
    231        final long last = value;
    232        value--;
    233        return last;
    234    }
    235
    236    /**
    237     * Increments this instance's value by 1; this method returns the value associated with the instance
    238     * immediately prior to the increment operation. This method is not thread safe.
    239     *
    240     * @return the value associated with the instance before it was incremented
    241     * @since 3.5
    242     */
    243    public long getAndIncrement() {
    244        final long last = value;
    245        value++;
    246        return last;
    247    }
    248
    249    /**
    250     * Gets the value as a Long instance.
    251     *
    252     * @return the value as a Long, never null
    253     */
    254    @Override
    255    public Long getValue() {
    256        return Long.valueOf(this.value);
    257    }
    258
    259    /**
    260     * Returns a suitable hash code for this mutable.
    261     *
    262     * @return a suitable hash code
    263     */
    264    @Override
    265    public int hashCode() {
    266        return (int) (value ^ (value >>> 32));
    267    }
    268
    269    /**
    270     * Increments the value.
    271     *
    272     * @since 2.2
    273     */
    274    public void increment() {
    275        value++;
    276    }
    277
    278    /**
    279     * Increments this instance's value by 1; this method returns the value associated with the instance
    280     * immediately after the increment operation. This method is not thread safe.
    281     *
    282     * @return the value associated with the instance after it is incremented
    283     * @since 3.5
    284     */
    285    public long incrementAndGet() {
    286        value++;
    287        return value;
    288    }
    289
    290    // shortValue and byteValue rely on Number implementation
    291    /**
    292     * Returns the value of this MutableLong as an int.
    293     *
    294     * @return the numeric value represented by this object after conversion to type int.
    295     */
    296    @Override
    297    public int intValue() {
    298        return (int) value;
    299    }
    300
    301    /**
    302     * Returns the value of this MutableLong as a long.
    303     *
    304     * @return the numeric value represented by this object after conversion to type long.
    305     */
    306    @Override
    307    public long longValue() {
    308        return value;
    309    }
    310
    311    /**
    312     * Sets the value.
    313     *
    314     * @param value  the value to set
    315     */
    316    public void setValue(final long value) {
    317        this.value = value;
    318    }
    319
    320    /**
    321     * Sets the value from any Number instance.
    322     *
    323     * @param value  the value to set, not null
    324     * @throws NullPointerException if the object is null
    325     */
    326    @Override
    327    public void setValue(final Number value) {
    328        this.value = value.longValue();
    329    }
    330
    331    /**
    332     * Subtracts a value from the value of this instance.
    333     *
    334     * @param operand  the value to subtract, not null
    335     * @since 2.2
    336     */
    337    public void subtract(final long operand) {
    338        this.value -= operand;
    339    }
    340
    341    /**
    342     * Subtracts a value from the value of this instance.
    343     *
    344     * @param operand  the value to subtract, not null
    345     * @throws NullPointerException if the object is null
    346     * @since 2.2
    347     */
    348    public void subtract(final Number operand) {
    349        this.value -= operand.longValue();
    350    }
    351
    352    /**
    353     * Gets this mutable as an instance of Long.
    354     *
    355     * @return a Long instance containing the value from this mutable, never null
    356     */
    357    public Long toLong() {
    358        return Long.valueOf(longValue());
    359    }
    360
    361    /**
    362     * Returns the String value of this mutable.
    363     *
    364     * @return the mutable value as a string
    365     */
    366    @Override
    367    public String toString() {
    368        return String.valueOf(value);
    369    }
    370
    371}