How do I increment a Integer's value in Java? I know I can get the value with intValue, and I can set it with new Integer(int i).
playerID.intValue()++;
does not seem to work.
Note: PlayerID is a Integer that has been created with:
Integer playerID = new Integer(1);
Integer objects are immutable, so you cannot modify the value once they have been created. You will need to create a new Integer and replace the existing one.
playerID = new Integer(playerID.intValue() + 1);
As Grodriguez says, Integer objects are immutable. The problem here is that you're trying to increment the int value of the player ID rather than the ID itself. In Java 5+, you can just write playerID++.
As a side note, never ever call Integer's constructor. Take advantage of autoboxing by just assigning ints to Integers directly, like Integer foo = 5. This will use Integer.valueOf(int) transparently, which is superior to the constructor because it doesn't always have to create a new object.
Java 7 and 8. Increment DOES change the reference, so it references to another Integer object. Look:
#Test
public void incInteger()
{
Integer i = 5;
Integer iOrig = i;
++i; // Same as i = i + 1;
Assert.assertEquals(6, i.intValue());
Assert.assertNotEquals(iOrig, i);
}
Integer by itself is still immutable.
AtomicInteger
Maybe this is of some worth also: there is a Java class called AtomicInteger.
This class has some useful methods like addAndGet(int delta) or incrementAndGet() (and their counterparts) which allow you to increment/decrement the value of the same instance. Though the class is designed to be used in the context of concurrency, it's also quite useful in other scenarios and probably fits your need.
final AtomicInteger count = new AtomicInteger( 0 ) ;
…
count.incrementAndGet(); // Ignoring the return value.
Integer objects are immutable. You can't change the value of the integer held by the object itself, but you can just create a new Integer object to hold the result:
Integer start = new Integer(5);
Integer end = start + 5; // end == 10;
For Java 7, increment operator '++' works on Integers. Below is a tested example
Integer i = new Integer( 12 );
System.out.println(i); //12
i = i++;
System.out.println(i); //13
Maybe you can try:
final AtomicInteger i = new AtomicInteger(0);
i.set(1);
i.get();
You can use IntHolder as mutable alternative to Integer. But does it worth?
All the primitive wrapper objects are immutable.
I'm maybe late to the question but I want to add and clarify that when you do playerID++, what really happens is something like this:
playerID = Integer.valueOf( playerID.intValue() + 1);
Integer.valueOf(int) will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
After Java 8, we can use as below
import java.lang.Math;
Math.incrementExact(playerID);
//it increment the integer value to + 1. It is also available for long
Related
What is the difference between them?
l is an arraylist of Integer type.
version 1:
int[] a = new int[l.size()];
for (int i = 0; i < l.size(); i++) {
a[i] = l.get(i);
}
return a;
version 2:
int[] a = new int[l.size()];
for (int i = 0; i < l.size(); i++) {
a[i] = l.get(i).intValue();
}
return a;
l.get(i); will return Integer and then calling intValue(); on it will return the integer as type int.
Converting an int to Integer is called boxing.
Converting an Integer to int is called unboxing
And so on for conversion between other primitive types and their corresponding Wrapper classes.
Since java 5, it will automatically do the required conversions for you(autoboxing), so there is no difference in your examples if you are working with Java 5 or later. The only thing you have to look after is if an Integer is null, and you directly assign it to int then it will throw NullPointerException.
Prior to java 5, the programmer himself had to do boxing/unboxing.
As you noticed, intValue is not of much use when you already know you have an Integer. However, this method is not declared in Integer, but in the general Number class. In a situation where all you know is that you have some Number, you'll realize the utility of that method.
The Object returned by l.get(i) is an instance of the Integer class.
intValue() is a instance method of the Integer class that returns a primitive int.
See Java reference doc...
http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html#intValue()
Java support two types of structures first are primitives, second are Objects.
Method that you are asking, is used to retrieve value from Object to primitive.
All java types that represent number extend class Number. This methods are in someway deprecated if you use same primitive and object type since [autoboxing] was implemented in Java 1.5.
int - primitive
Integer - object
Before Java 1.5 we was force to write
int i = integer.intValue();
since Java 1.5 we can write
int i = integer;
Those methods are also used when we need to change our type from Integer to long
long l = integer.longValue();
Consider this example:
Integer i = new Integer(10);
Integer j = new Integer(10);
if (!(i == j)) {
System.out.println("Surprise, doesn't match!");
}
if (i.intValue() == j.intValue()) {
System.out.println("Cool, matches now!");
}
which prints
Surprise, doesn't match!
Cool, matches now!
That proves that intValue() is of great relevance. More so because Java does not allow to store primitive types directly into the containers, and very often we need to compare the values stored in them. For example:
oneStack.peek() == anotherStack.peek()
doesn't work the way we usually expects it to work, while the below statement does the job, much like a workaround:
oneStack.peek().intValue() == anotherStack.peek().intValue()
get(i) will return Integer object and will get its value when you call intValue().In first case, automatically auto-unboxing happens.
They are exactly the same. As other posters have mentioned, you can put either the Integer object or the int primitive into the array. In the first case, the compiler will automatically convert the Integer object into a primitive. This is called auto-boxing.
It's just a convenience method for getting primitive value from object of Number: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Number.html
Consider the code:
Integer integerValue = Integer.valueOf(123);
float floatValue = integerValue.floatValue();
The last line is a convenient method to do:
float floatValue = (float)(int)integerValue;
Since any numeric type in Java can be explicitly cast to any other primitive numeric type, Number class implements all these conversions. As usual, some of them don't make much sense:
Integer integerValue = Integer.valueOf(123);
int intValue = integerValue.intValue();
int intValue2 = (int)integerValue;
int intValue3 = integerValue;
I would like to know when I am checking for integers input, should I use int or Integer for checking?
Below is some mock-up codes:
This one uses int:
public State editState (int stateID, String stateCode) {
if (stateID == 0) {
throw new Exception("State id not set.");
}
...
State s = new State();
...
return s;
}
This one uses Integer:
public State editState (Integer stateID, String stateCode) {
if (stateID == null) {
throw new Exception("State id not set.");
}
...
State s = new State();
...
return s;
}
Which approach is better in use?
when you will invoke editState(..,..) and stateId is not set then two cases arise-
1)editState(0,"some code");
2)editState(null,"some code");
It depends upon the criteria you set for the unacceptance of stateID.
If you set criteria for unacceptance as null then you will have to use 'Integer'
and if 0 then you can use both 'Integer' and 'int' ...
so it depends upon the criteria you set at the invoking side..
And i think Integer (wrapper class ) is better due to excellent auto boxing ,unboxing features
as well as various methods provided to you for manipulations if required...
There is no much difference performance wise or functionality wise. Both would be almost equal. It depends more on how the input is in the method invoking the editState(...) method. If the invoking method has primitive type int or wrapper Integer, corresponding editState(...) is better to use.
Also, if the invoking method has the possibility of different numeric types (byte, short etc.) that fits into int, then first one is preferred. Similarly if it has object that can be autoboxed to Integer, then second one is preferred.
Well, in Java an int is a primitive while an Integer is an Object. Meaning, if you made a new Integer:
Integer i = new Integer(6);
You could call some method on i:
String s = i.toString(); //sets s the string representation of i
Whereas with an int:
int i = 6;
You cannot call any methods on it, because it is simply a primitive. So:
String s = i.toString(); //will not work!!!
would produce an error, because int is not an object.
I think if you have not any requirement to use such operation then go with int instead of Integer and you can also avoid a unnecessary Java object creation.
Let's say that I have a class:
class A {
private Integer i;
public int getI() {
return i;
}
// Setter, etc.
}
and I write:
A a = // initializer
Integer b = a.getI();
how many Integers will there be? My naive reading about autoboxing/unboxing leads me to believe that the answer is 2, but if getI() were:
public Integer getI();
then the answer would be 1.
You are absolutely correct, with one caveat: the answer to the first part depends on the value of Integer i.
In the first scenario, one Integer is created in the constructor, and the other one is created when boxing the int coming from getI()
In the second scenario, there needs to be no boxing, so there's only one Integer object.
Note: if the value of the Integer i is small (more precisely, between -128 and 127, inclusive), autoboxing will produce the same Integer through interning.
Correct....ish
It's theoretically possible the Compiler/JIT/JVM/etc could optimise out the autoboxing but I've no idea if it actually would.
It's also possible the same Integer object would be re-used. For example Integer.valueOf(2) is guaranteed to give you the same Integer object every time you call it and re-use the same object. This is only guaranteed for values in the range -128 to +127 inclusive though, it may happen outside that range but should not be relied upon.
I have the following piece of Java code using HashMap and generics:
import java.util.*;
import java.io.*;
public class Map{
static HashMap<Integer, Integer> imap;
static HashMap<Integer, Thing> tmap;
public static void main(String[] args){
imap = new HashMap<Integer, Integer>();
imap.put(0,0);
Integer i = imap.get(0);
i = i + 1;
System.out.println(imap.get(0));
tmap = new HashMap<Integer, Thing>();
tmap.put(0,new Thing(0));
Thing t = tmap.get(0);
t.a = t.a + 1;
System.out.println(tmap.get(0).a);
}
}
class Thing{
public int a;
public Thing(int n){
this.a = n;
}
}
which prints out the following:
0
1
I would expect it to print either both ones (if I were modifying the reference) or both zeros (if I were modifying the values). So why is the behaviour different for a map from integer to integer than from integer to thing?
Java's integer types are not mutable, so your first example takes the value from the map, then replaces the local variable with the new value. However, the second example gets a reference to the Thing instance from the map.
By doing i=i+1 you are incrementing not the value stored in the java.lang.Integer contained in the map.
I think i = i + 1; will not be updated on the object because the get will be a copy by value as you assigning to a primitive. The primitive update will therefore not reflect in the map as you don't hold a reference. With the next example in Thing you are directly assigning back to the public primitive of the Thing, so again by value - but you update the public int.
It's because you're auto-unboxing the Integer value when you grab it from the first map (by assigning an Integer to an int). At that point you're not using an Integer reference, you're using an int primitive, with no relationship to the Integer reference held in the map.
As java Integers are immutable, there's really no way to do what you're trying to demonstrate here. There is no way to modify the internal primitive int held by the Integer reference in the map. You'd have to .put a new Integer to change the value held at key 0.
Answering the second part of the question ("But then why does it print 1 on the second print statement?"), it's because the lines ...
Thing t = tmap.get(0);
t.a = t.a + 1;
... get you a reference to the object located within the hashmap at a given location, and then modify a member variable of the referenced object. The println statement then retrieves another reference to that same object with the now-modified member variable.
There's a general advice to use Integer.valueOf(int) instead of new Integer(int) because of caching.
In JDK 5+, you should really use valueOf because Integer now caches Integer objects between -128 and 127 and can hand you back the same exact Integer(0) object every time instead of wasting an object construction on a brand new identical Integer object.
How can extend the range?
You can use the java.lang.Integer.IntegerCache.high property to increase the size of this cache.
ex :
java -Djava.lang.Integer.IntegerCache.high=4096 SomeClass.class
My questions to you are:
1) Why is your code making new Integer objects hurting you? Do you have a profile result to share, to prove that making too many Integers is slowing your down? Object pooling, in general, is a BAD idea. You need a good case to justify it.
2) Why are you doing new Integer(int)? If you just keep it as a primitive int, not only will you avoid "creating a new object". you will not create any object at all. Auto boxing will handle converting it to an Integer if you need it at a later point in time.
*Disclaimer I Don't use EITHER.. I write performance sensitive code, but have never come to a point where I would manually turn a primitive int into an Integer. I just keep as an int whenever possible, and let the JVM autobox if it is needed.
Apparently, the -XX:+AggressiveOpts sets the max to 20000. See the answer on How large is the Integer cache?
Extending the range of the cache may not get you what you are wanting, but if you have a real need to cache a greater range, you can use this code instead of Integer.valueOf(int). You just need to adjust the cache range values to the range you want.
private static class IntegerCache
{
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static
{
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
public static Integer valueOf(int i)
{
final int offset = 128;
if (i >= -128 && i <= 127) // must cache
{
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
The code is from: http://www.owasp.org/index.php/Java_gotchas
This is why the integer cache was added:
[...] to support the object identity semantics of autoboxing for values between -128 and 127 (inclusive), as required by the language specification.
If you profiled your app and you noticed that creating Integer objects is a hotspot, then by all means, copy the integer cache code and write your own with a different range. Otherwise your time would be better spent finding the real hotspots and improving those.