Why doesn't Integer have a setValue(int i), and is there a way of changing its value.

N

natG

Hi folks;

Am I missing something(again)?
It seems that one cannot set the int value represented by an Integer object once
the Integer is created.
Pray tell me I'm wrong, and why is this so.

Thanks
-nat
 
J

Jarmo

natG said:
Hi folks;

Am I missing something(again)?
It seems that one cannot set the int value represented by an Integer object once
the Integer is created.
Pray tell me I'm wrong, and why is this so.

Thanks
-nat

Just create a new Integer, constructed with the new value. And, generally
speaking, I would use the native 'int' rather than the 'Integer' class to
store integer values unless you absolutely have to use the latter e.g.
because you need to store them in a Hashtable.
 
L

Lee Weiner

Hi folks;

Am I missing something(again)?
It seems that one cannot set the int value represented by an Integer object
once
the Integer is created.
Pray tell me I'm wrong, and why is this so.

You're not missing anything. Integer, like all the "wrapper" classes (Double,
Character, etc.) are immutable, once created the value may not change. They
are provided specifically for when you want to store a primitive value in a
structure that only accepts objects, like ArrayList, LinkedList, HashTable,
etc.

As to why they're immutable, I don't know. I learned a long time ago, asking
those kinds of questions is less than useless.

When you want to change a value, just assign a new object:

Integer hello = new Integer(10);

// now I need a new value

hello = new Integer(5);

Lee Weiner
lee AT leeweiner DOT org
 
N

natG

Thank you for your replies.
In this case I need an Integer becuase its stored in an Object[] array.
My specific problem is that some of these Integers, for whatever reason, have to
change their value pretty often.
My concern was for the huge amount of garbage generated by constantly doing
"Object[x] = new Integer(y);", hence this post.

Thanks again for the clarification, and please advise if you feel I should not be
concerned about the garbage. The aforementioned code (...= new Integer(y)) might
happen about 1500 times per hour!
Of course I can re-design a few classes, but first I wanted to verify if its
indeed immutable.

-nat
 
S

Sudsy

natG said:
Thank you for your replies.
In this case I need an Integer becuase its stored in an Object[] array.
My specific problem is that some of these Integers, for whatever reason, have to
change their value pretty often.
My concern was for the huge amount of garbage generated by constantly doing
"Object[x] = new Integer(y);", hence this post.

You realize that you can use an Object like a C struct, right?

public class MyInteger {
public int value;

public MyInteger( int i ) {
value = i;
}
}

Create it like this:

MyInteger I = new MyInteger( 3 );

Then access or mutate the value directly:

I.value = 4;
System.out.println( "Value = " + I.value );

Works for me!
 
N

natG

It's something I considered but put it off because of other uses of this Integer
that will force me to duplicate quite a few Integer methods. For starters:
hashCode, equals, compareTo, toString, and then some.
(Slowly but surely I might fall to "api creep", until MyInteger has all the
functionality of Integer when I realize why it HAS to be immutable<g>! nah..)

It seems like the route I will have to take, though.

By the way, what's a good hashCode for a simple thing like that?

thanks
-nat


Sudsy said:
natG said:
Thank you for your replies.
In this case I need an Integer becuase its stored in an Object[] array.
My specific problem is that some of these Integers, for whatever reason, have to
change their value pretty often.
My concern was for the huge amount of garbage generated by constantly doing
"Object[x] = new Integer(y);", hence this post.

You realize that you can use an Object like a C struct, right?

public class MyInteger {
public int value;

public MyInteger( int i ) {
value = i;
}
}

Create it like this:

MyInteger I = new MyInteger( 3 );

Then access or mutate the value directly:

I.value = 4;
System.out.println( "Value = " + I.value );

Works for me!
 
J

Jon Skeet

natG said:
The aforementioned code (...= new Integer(y)) might
happen about 1500 times per hour!

1500 times per hour is absolutely nothing. I've just written a program
to generate 1500 of them 100,000 times - and it took about 3 seconds.
Just don't worry about it at all.
 
A

Andrew Thompson

Jon Skeet said:
1500 times per hour is absolutely nothing. I've just written a program
to generate 1500 of them 100,000 times

I'm curious Jon, as to the nature of the program
you just wrote that requires/generates 150 _million_
integer objects?

Are you writing weather modelling apps?
 
D

Darryl L. Pierce

natG said:
Am I missing something(again)?

Yes. ;)
It seems that one cannot set the int value represented by an Integer
object once the Integer is created.
Pray tell me I'm wrong, and why is this so.

Integer, like the wrappers for the other primitives and String, is
*immutable*. This gives the compiler the ability to optimize its usage when
compiling code.
 
B

Bent C Dalager

As to why they're immutable, I don't know. I learned a long time ago, asking
those kinds of questions is less than useless.

I believe the reason is that for a wide range of uses, immutable is
safer. As I recall, Sun is very clear about this when it comes to the
String class, and I suspect much of the same reasoning lies behind the
primitive-wrappers.

Cheers
Bent D
 
S

Sudsy

natG said:
It's something I considered but put it off because of other uses of this Integer
that will force me to duplicate quite a few Integer methods. For starters:
hashCode, equals, compareTo, toString, and then some.
(Slowly but surely I might fall to "api creep", until MyInteger has all the
functionality of Integer when I realize why it HAS to be immutable<g>! nah..)

It seems like the route I will have to take, though.

By the way, what's a good hashCode for a simple thing like that?

thanks
-nat

You inherit the hashCode implementation from Object. As to the
others, it's easy:

public boolean equals( Object o ) {
return( ( o instanceof MyInteger ) &&
( value == ( (MyInteger) o ).value ) );
}

public int compareTo( MyInteger I ) {
return( value - I.value );
}

public String toString() {
return( "" + value );
}

Sudsy
 
N

natG

Can you please explain "safer"? Do I practice SAFE Java<g>?
Seriously, safer in what respect?
Thanks
-nat
 
N

natG

Thank you much.
Regarding hashCode, I thought that whenever you override equals (an toString?) you
also have to
implement a new hashCode algorithm. The reason for this (the relationship between
these methods) always eluded me.

-nat
 
A

Alex Hunsley

natG said:
Can you please explain "safer"? Do I practice SAFE Java<g>?
Seriously, safer in what respect?
Thanks
-nat

[top posting fixed]

It's harder to make coding mistakes when wrappers like Integer are
immutable. And with such a simple object, it's just as easy to make a
new one as it would be to call Integer.setValue().
(By coding mistakes I refer to situations where, for example, you change
an Integer object that is also referenced somewhere else, which will
then run into problems because the value has changed etc.)

(An added benefit is that the system can cache existing Integer objects
- no matter how many times you call new Integer(1), there is only one in
existence (I would presume).

Can you please not top post, btw? It makes threads easier to follow if
you bottom post.

http://www.ptialaska.net/~kmorgan/nquote.html
http://www.zedtoo.demon.co.uk/jcode/basic.html
http://www.netmeister.org/news/learn2quote2.html#ss2.3




alex
 
S

Sudsy

natG said:
Thank you much.
Regarding hashCode, I thought that whenever you override equals (an toString?) you
also have to
implement a new hashCode algorithm. The reason for this (the relationship between
these methods) always eluded me.

I've never heard of such a rule. According to the javadocs for
Object#hashCode:

"This is typically implemented by converting the internal address of
the object into an integer, but this implementation technique is not
required by the JavaTM programming language."

Sounds good enough for me! As to the equals, only an implementation
can decide what equality means. The toString method is often used to
generate something like classname@hashCode, although it can also be
coded to dump the internal object state. In the simple case (this
one) we can just return the value, just like Integer#toString does.
 
B

Bent C Dalager

Two cases spring immediately to mind.

If you use instances of the class as keys in a Map, or you have them
in a Collection that you expect to always be sorted, then immutability
guarantees that your sorting won't inadvertantly get screwed up by
someone calling a setter at inopportune times. With immutable keys,
the only thing that can mess with your sorting is when the
Collection's setters are called. The alternative to immutability would
be for the class to fire events whenever you changed something and the
Collections classes to be sensitive to such events and be able to
auto-resort themselves, but this gets real messy real quick.

Also, for String, allowing it to be changed at any time would be a
security hazard when used within security-sensitive library
functions. As an example, I could send in username "guest" and
password "guest" as Strings to some function and then at some later
time, after I had been authenticated, change the contents of the
username String to "root". Unless the library was carefully written,
this has the potential of being a security problem. As things are, the
fewer of these pitfalls exist, the better.

How many of your methods take some object instance as parameter, hang
on to it and expect it not to change thereafter? Any that do are
vulnerable to malfunction when the instance gets mutated from the
outside.
[top posting fixed]

Thank you :)

Cheers
Bent D
 
M

Marco

That's true (except the bit about toString(). toString()
isn't related to equals() or hashCode()).

If you change the semantics of equals(), you should
override hashCode() too. If a.equals(b) is true, then
a.hashCode() == b.hashCode() must also be true.

If not, and you store these objects in a hash table ( e.g.
java.util.HashMap, java.util.HashSet or java.util.Hashtable),
they'll be hashed and coerced into different buckets. In
other words, they'll be treated as separate keys even though
your definition of equals() says they're identical.

Example:
Suppose you define a class like this, defining specialized
equals() semantics without a matching hashCode()...

class IntegerWrapper extends Object {
int value;
public IntegerWrapper(int value) {
this.value = value;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if ( obj == null || this.getClass() != obj.getClass() )
return false;
IntegerWrapper other = (IntegerWrapper) obj;
return this.value == other.value;
}
}

....and then use instances of this class in a hash table,
like this...

class Test {
public static void main(String[] args) {
HashMap hm = new HashMap();
hm.put( new IntegerWrapper(5), "hello" );
hm.put( new IntegerWrapper(5), "goodbye" );
Object obj = hm.get( new IntegerWrapper(5) );
System.out.println(obj);
}
}

What do you think will be printed out? "hello", "goodbye"
or null? The answer is null, even though
IntegerWrapper.equals() defines these 3 instances as equal:

new IntegerWrapper(5)
new IntegerWrapper(5)
new IntegerWrapper(5)

Marco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top