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