Updating an object in a HashMap

A

alacrite

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

Thanks.
 
M

Matt Humphrey

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

The problem here is that Integers (along with Strings, Doubles, etc) are
immutable. For Integer i, the expression i += 5 is autoboxing shorthand for

i = new Integer (i.intValue() + 5)

hm.get("test1") gives you the reference to Integer object, but is not itself
a variable that can be assigned to--it's just the returned expression value
(in this case the reference) Instead you must do

hm.put("test1", hm.get("test1") + 5)

Note that if you had an array of integers Integer [] iarray. you could say
iarray[j] += 5; because iarray[j] does work as a variable.

Matt Humphrey http://www.iviz.com/
 
A

Arne Vajhøj

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

The left hand side is not a literal.

It is an expression and you can not assign to an expression.

Arne
 
K

Knute Johnson

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;

// the equivalent of this line is
// 0 += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

Thanks.

int newValue = hm.get("test1") + 5;
hm.put("test1",newValue);
 
L

Lew

Arne said:
import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

The left hand side is not a literal.

It is an expression and you can not assign to an expression.

For example, the statements

int i;
(i) = 5;

would also fail to compile.
 
J

John W. Kennedy

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0.

hm.get returns the Integer, but then you've done intValue of that, and
that's a plain int.
I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Before you called intValue, you had a reference to the original Integer,
but Integer objects (just like Boolean, Byte, Short, Character, Long,
Float, Double, and String) are immutable. But after intValue, you had a
plain int, and you can't have a reference to a boolean, byte, short,
char, long, float, or double -- only objects.
Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

Since the Integer is immutable, you have to replace it with a new one.

hm.put("test1", hm.get("test1") + 5);

Autoboxing and unboxing translates this, in effect, to

hm.put("test1", new Integer(hm.get("test1").intValue + 5));

If the case were different -- say you were using an imaginary type
called "MutableInteger" -- you could do something like this:

hm.put("test1", new MutableInteger(0));
hm.get("test1").MutableInteger.add(5));
 
D

Daniel Pitts

Matt said:
import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

The problem here is that Integers (along with Strings, Doubles, etc) are
immutable. For Integer i, the expression i += 5 is autoboxing shorthand for

i = new Integer (i.intValue() + 5)
<pedantry>
Actually, its short hand for i = Integer.valueOf(i.intValue()+5);
valueOf does some interning for a specific range of numbers.
hm.get("test1") gives you the reference to Integer object, but is not itself
a variable that can be assigned to--it's just the returned expression value
(in this case the reference) Instead you must do

hm.put("test1", hm.get("test1") + 5)

Note that if you had an array of integers Integer [] iarray. you could say
iarray[j] += 5; because iarray[j] does work as a variable.

Matt Humphrey http://www.iviz.com/

Alternatively, you could do this:

public class IntWrapper {
private int value;
public void incBy(int inc) {
value += inc;
}
}

Map<String, IntWrapper> hm = getHm();
hm.get("test1").incBy(5);
 
A

alacrite

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

Thanks.

Thank you all for your replies. I did not realize that Boolean, Byte,
Short, Character, Long,
Float, and Double objects were immutable.
 
M

Mark Space

Lew said:
For example, the statements

int i;
(i) = 5;

would also fail to compile.

So does that mean that (i) is an r-value in Java? And are only
primitives (and references, being one type of primitive) assignable in
Java? Are primitives the only l-value in Java?

I could probably get off my lazy tush and look this up in the JLS, but I
though it might be interesting topic for discussion. (Thereby
justifying my laziness.)

And autoboxing with the Object forms of the primitives looks like it's
been crowbarred to update the reference, not the Object....
 
L

Lew

Mark said:
So does that mean that (i) is an r-value in Java? And are only
primitives (and references, being one type of primitive) assignable in
Java? Are primitives the only l-value in Java?

I'm not sure Java talks about r-values and l-values. The bottom line is that
only variables can have values assigned to them.

As an old C programmer myself, I think of variables as l-values, but really
that's not the Java terminology AIUI.
And autoboxing with the Object forms of the primitives looks like it's
been crowbarred to update the reference, not the Object....

I'm not sure exactly how you mean that. What do you mean by "crowbarred"?

There's no way to "update" a number wrapper class object like an Integer once
instantiated. So only the reference, i.e., the variable even can be updated.

Autoboxing causes a sequence like

Integer foo = new Integer( 17 );
foo += 23;

to assign a new Integer instance to foo. No Integer object is changed; the
Integer representing 17 is dropped and a new one referenced. Because values
from -128 to 127 are sort-of interned, and a larger range could be, there is
pretty likely no GC involved.
<http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7>
 
D

Daniele Futtorovic

import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

Thanks.

Thank you all for your replies. I did not realize that Boolean, Byte,
Short, Character, Long,
Float, and Double objects were immutable.

This has NOTHING to do with immutable or not.

Two replies have stated this. Though their work-around was correct,
their reason was plain wrong.

It has NOTHING to do with immutability. It has to do with what's a valid
statement and what's not, more precisely what's a valid assignment
statement and what's not.

See:
<http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5281>

It defines the LeftHandSide (LHS) and states accordingly:
"The result of the first operand [<=> LHS] of an assignment operator
must be a variable, or a compile-time error occurs. This operand may be
a named variable, such as a local variable or a field of the current
object or class, or it may be a computed variable, as can result from a
field access (§15.11) or an array access (§15.13)"

That is why. <rant>As your compiler clearly told you.</rant>

@Lew: the page just referred to mentions lvalues, which I too had until
now thought common terminology in Java, on the top of the page. That's
one of only two results a google search with
"site:http://java.sun.com/docs/books/jls/third_edition/html/expressions.html"
yielded.

DF.
 
A

Arne Vajhøj

Thank you all for your replies. I did not realize that Boolean, Byte,
Short, Character, Long,
Float, and Double objects were immutable.

They are.

But that was not the cause of your error message.

Arne
 
J

John W. Kennedy

Daniele said:
import java.util.HashMap;
import java.lang.System;;

public class HashMapTest
{
public static void main(String args[])
{
HashMap<String,Integer> hm = new
HashMap<String,Integer>();

hm.put("test1",0);

hm.get("test1").intValue() += 5;
//Error:The left-hand side of an assignment must be a
variable

System.out.println(hm.get("test1"));
}

}

I want to update a Value in a HashMap. I know the Key. I would have
assumed the above code would work. Instead, I am given an error, "The
left-hand side of an assignment must be a variable".

Does this mean that the value returned is the literal value? In this
case 0. I would have assume a reference to the object would have been
returned and calling += would have unboxed the Integer and aggregated
the value.

Could someone explain to me what is going on? Also, what is the best
way to accomplish updating this value?

Thanks.

Thank you all for your replies. I did not realize that Boolean, Byte,
Short, Character, Long,
Float, and Double objects were immutable.

This has NOTHING to do with immutable or not.

Two replies have stated this. Though their work-around was correct,
their reason was plain wrong.

It has NOTHING to do with immutability.

His original mistake had a great deal to do with his failure to
apprehend that immutability.
--
John W. Kennedy
"Those in the seat of power oft forget their failings and seek only the
obeisance of others! Thus is bad government born! Hold in your heart
that you and the people are one, human beings all, and good government
shall arise of its own accord! Such is the path of virtue!"
-- Kazuo Koike. "Lone Wolf and Cub: Thirteen Strings" (tr. Dana Lewis)
 
J

John W. Kennedy

Arne said:
They are.

But that was not the cause of your error message.

He understood the message. ("Does this mean that the value returned is
the literal value? In this case 0.") What he did not understand was the
underlying situation. ("I would have assume a reference to the object
would have been returned and calling += would have unboxed the Integer
and aggregated the value.")
 
D

Daniele Futtorovic

His original mistake had a great deal to do with his failure to
apprehend that immutability.

His first question was:
I would have assumed the above code would work. Instead, I am given
an error, "The left-hand side of an assignment must be a variable".

This error had clearly nothing to do with immutability.

Maybe you're right in assuming the source of his mistake was as you say,
but this is not the impression I got. It seemed much more he had no
clear understanding of what a reference is, and that you need one as the
LHS of an assignment. On second thought, you're probably right in that
he would have stumbled upon immutability next, as it is hidden by that
autoboxing crap. One more case where it leads to confusion.

df.
 
A

Arne Vajhøj

John said:
He understood the message. ("Does this mean that the value returned is
the literal value? In this case 0.")

Left side was not a literal values.
What he did not understand was the
underlying situation. ("I would have assume a reference to the object
would have been returned and calling += would have unboxed the Integer
and aggregated the value.")

It still does not have anything to do with the fact that it was
an immutable object.

An expression on the left side of "=" does not work - immutable
or mutable.

Arne
 

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

No members online now.

Forum statistics

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

Latest Threads

Top