102

I am in a situation where I want to use mutable versions of things like Integer. Do I have to use these classes (below) or does Java have something built in?

http://www.java2s.com/Code/Java/Data-Type/Amutableintwrapper.htm

smuggledPancakes
  • 9,881
  • 20
  • 74
  • 113
  • 9
    The question is why do you want to do this? – helpermethod Dec 23 '10 at 15:41
  • 3
    For some cases (eg. a game, storing a piece of food carrying `n` calories, which can be depleted/added to), it might be better to use a class named after the use, (eg. `class FoodItem { int calories; }`, because it is clearer and methods can be added if needed later. – GKFX Jul 29 '14 at 12:42
  • 8
    Java 8 lambdas work only with effectively final variables. To work around this limitation a mutable int is needed. – Alex Mar 22 '17 at 12:58
  • 3
    You may want a counter which needs to be passed between methods. Passing an `int` doesn't work as if it is incremented in one method then the value won't be reflected in the other method. – Adam Burley Apr 15 '20 at 17:32

7 Answers7

110

You could always wrap the value in an array like int[] mutable = {1}; if including the code for a mutable wrapper class is too cumbersome.

Alex Jasmin
  • 39,094
  • 7
  • 77
  • 67
65

No, Java doesn't have these built in. And that is for a reason. Using mutable types is dangerous, as they can easily be misused. Additionally, it is really easy to implement it. For example, commons-lang has a MutableInt.

Valentin Michalak
  • 2,089
  • 1
  • 14
  • 27
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 7
    My guess is the java dev's wanted Integer to 'behave' like an int, which is..once you have a reference to it, it never changes (avoid confusion). But..it still seems odd to not have a mutable option somehow, to me... – rogerdpack Feb 11 '13 at 23:02
  • 45
    "Using mutable types is dangerous because they can easily be misused." Most things can be misused. Immutable types exist for cases where safety is important, although they can be changed by reflection. With those cases out of the way, there's no reason to prevent people from using mutable types when they need them. – GKFX Jul 29 '14 at 12:36
  • 2
    A better way to put it, immutable types create less confusion in e.g. maps and sets. If you had a mutable Integer and changed its value where it served as a key, it would mess up the collection. However, in case you need some mutable implementation of Integer, nothing is easier than creating some class with an int value inside. And you can be creative there - make it e.g. a Counter or Countdown, not just a plain int that enables quite anything. Give it some logic (unless you develop in Java EE that works bottoms-up). – Vlasec Aug 05 '14 at 10:42
  • 1
    Certainly an old question, but hopefully someone can answer HOW they can be misused. What is so dangerous about using them? – The Fluffy Robot Aug 10 '17 at 13:14
  • @user1175807 As Vlasec had commented, if you accidentaly modify a variable you have used somewhere else, it will cause weird bugs. Even worse, let's say you're writing a program that works together with a client's code. You need to implement a method which has a parameter of mutable Integer type. Now if you modify the mutable Integer for any reason, then it would also be changed in the client's program, which is totally unexpected, and will cause bugs that are hard to find. – GregT Nov 13 '17 at 15:18
62

Since JDK 1.5 java now has java.util.concurrent.atomic.AtomicInteger

This is a thread safe mutable integer, example of use:

final AtomicInteger value = new AtomicInteger(0);

then later on:

value.incrementAndGet();
Clive
  • 681
  • 5
  • 2
  • 21
    This thead safety comes at a performance cost, which in many cases is not needed. For example, a common use case for me is to increment a counter captured by a lambda. Using an atomic is overkill. – Minas Mina May 18 '18 at 12:53
13

Here's a small class I made for a mutable integer:

public class MutableInteger {
    private int value;
    public MutableInteger(int value) {
        this.value = value;
    }
    public void set(int value) {
        this.value = value;
    }
    public int intValue() {
        return value;
    }
}

You could easily extend this to any other primitive. Of course, like everyone else is saying, you should use it carefully.

VinceFior
  • 1,279
  • 13
  • 25
  • 1
    IMHO the best option has it doesn't give false clues about concurrency as using an atomic interger does. And an array, really I would never do such a bad thing in my code.. ;) – Snicolas May 27 '15 at 22:51
  • 1
    Could be a good idea to provide a single generic wrapper class instead so You don't end up with a `MutableInteger`, `MutableDouble`, `MutableString` etc. but instead have a `Mutable`, `Mutable`, ... The memory overhead (of using `Integer` over `int` will usually not fall into account. But you get a single, ready to use class that can handle most cases (If you want your integer to be comparable or similar things you still need to subclass, though). – Qw3ry Jan 07 '17 at 18:46
  • It might be a good idea to make it extend [Number](https://docs.oracle.com/javase/8/docs/api/java/lang/Number.html). – Stijn de Witt Jun 09 '17 at 21:54
6

AtomicInteger has already been mentioned. Mutable Doubles can be emulated with AtomicReference<Double>. The already mentioned warnings apply and it is bad style, but sometimes you have code like this

double sum=0
for (Data data:someListGenerator())
  sum+=data.getValue()

and want to refactor it in functional Java 8 style. If the code follows this pattern but adds considerable complexity to it, the most sensible conversion could be

AtomicReference<Double> sumref=new AtomicReference<>(0d);
someStreamGenerator().forEach(data->
  sumref.set(sumref.get().doubleValue()+data.getValue()));
double sum=sumref.get().doubleValue();

Of course, this is at least questionable style. But I found myself more than once in a situation with a twisted loop over a ResultSet computing and partly cumulating three different information from it. This makes it really hard to convert the code into proper functional style. Converting the cumulating parts according to the above pattern seemed to me a reasonable tradeoff between clean code and oversimplified refactoring.

Dirk Hillbrecht
  • 573
  • 5
  • 18
  • You should really think about your wording: Even if you use a lambda, your example is not _functional_, as that prohibits side effects. If you really write it functional, you don't need mutables: `someStreamGenerator().mapToDouble(Data::getValue).sum()`. Even for cumulating three different informations, there is a _functional_ way by using `Stream.reduce` or `Stream.collect`. I see no reason to refactor every loop to a functional code fragment, but if you want to go that way, you should go it until the end. – Tobias Liefke Oct 17 '18 at 10:01
  • 1
    As I wrote: This is _not_ proper style and for each and any new code this should _not_ be used. But when refactoring 400.000+ lines of code which evolved within 15+ years, you find constructs where proper rewrite into truly functional constructs can be _extremely_ difficult. Then, rewriting into such hybrid-style can be a sensible trade-off as you get at least the basic structure aligned. `for` and `foreach` can be parts of complex frameworks which are functionally rewritten, so you have to align the rest of the code somehow around them. – Dirk Hillbrecht Oct 17 '18 at 15:03
  • You are confusing lambdas and functional programming. In your example you didn't rewrite it "functional". And what is the point in rewriting everything with lambdas, when you lose readability, but don't get the advantages of functional programming? Why should one even try to get rid of every loop in a complex framework by using such hybrids? – Tobias Liefke Oct 18 '18 at 09:11
  • 1
    You have 1000 places with a certain idiom in your code. The idiom is driven by a library or whatever global structure. You replace that global structure with a new one based on functional approach and lambdas. 998 of your 1000 places can be converted cleanly into functional style. The remaining 2 are extremely difficult to convert properly. In such cases, I always mandate for converting into new style with such hybrid constructs. Only then you can get rid of whatever old global structures have been in the code. While not being perfect, the overall code quality increases. – Dirk Hillbrecht Oct 18 '18 at 13:20
6

You can use an nnnn[] as a mutable object for any primitive type as @Alexandre suggests, java also has AtomicInteger and AtomicLong.

IMHO int is usually a better choice than Integer and that is mutable.

Can you more details of why you need a mutliple object, perhaps there is another way to achieve the same thing.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 8
    `int` is always mutable unless its also `final` – Peter Lawrey Jan 31 '12 at 15:39
  • 19
    It's not really valid to say that a primitive type is **mutable**. It can be **changed** but so can every non-final object if you just point to a new object. For example `Integer a = 4;` then `a = 5;` is valid code, but `Integer` is not mutable. – mjaggard Feb 01 '12 at 09:08
  • I agree that `Integer` instances are not mutable even if references to them are, but that's a different type. – Peter Lawrey Feb 01 '12 at 09:34
  • Isn't this a good way to have a reference int parameter? For example a function that returns a paginated List of items (from the database), but also the total number of records. In such a case, AtomicInteger or MutableInteger seem to be useful. Of course the other way would be to have a getTotalRecords property instead of returning it in the same method. – msanjay Apr 24 '12 at 07:21
  • 2
    `int` is not mutable because if you pass it to a method, there is no way for the method to change its value and have the new value reflected in the calling method – Adam Burley Apr 15 '20 at 17:36
  • @AdamBurley while you cannot pass by reference any local variable this is not what is meant by mutuality. – Peter Lawrey Apr 20 '20 at 07:50
3

You can import the org.omg.CORBA package(or just the class you need) and in it you can use the Holder classes.

For example, it has the "IntHolder" where the field where it stores the integer is public, giving access to modify it.

public static void triple(IntHolder x){
    x.value = 3 * x.value;
}

IntHolder mutableInt = new IntHolder(10);
triple(mutableInt);     
System.out.println(mutableInt.value);

It also has "LongHolder" and "DoubleHolder" and tons of others that you can use. Use with caution.

Here is the api for it: https://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/package-summary.html

Erkan Uretener
  • 103
  • 1
  • 9
  • 2
    While very smart way to fix the problem, with Java9 coming up, you probably don't want to use this -- that would import the whole CORBA module just for an int holder. – Agoston Horvath Nov 25 '16 at 10:23