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