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