HashTable Issue
Asked Answered
T

6

6

I have an interesting question which entails the use of Hashtables; I'm developing for S40 Nokia's (with compliance level 1.4)

How I expect the Hashtable to work:

Hashtable table = new Hashtable();
table.put(1, "Hello World");

However I get the error:

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

However when I create an object reference and pass the reference, it works fine! Why?!

Working example:

Hashtable table = new Hashtable();
Integer test = new Integer(1);
table.put(test, "Hello World");

Any explanations would be great!

Tenuis answered 14/7, 2014 at 11:2 Comment(12)
Your code works fine on my end. Are you sure their isn't another underlining problem ? are you sure your Hashtable is of type import java.util.Hashtable;Enphytotic
@Enphytotic Using which JDK ??Baneberry
As far as you are developing for Nokia S40 I understand that this is J2ME. Is is a chance that you build your app using some additional tools, i.g. obfuscator, J2MEPolish etc?Gretta
I'm wondering... what happens if you do table.put(((Integer) new Integer(1)),"Hello World"); ?Hightension
Or you may try table.put((object)1,"Hello, World");Galenic
Autoboxing not available in Java 1.4, It was introduced in 1.5. That might be a problem.Monikamoniker
In the first case you lost the reference to the newly created Integer just after you put it in the table. There is no way to retrieve the object. But in the second case you maintain a reference outside, which can be used later to retrieve it.Monikamoniker
@Tenuis - are you sure you posted here the actual code which causes the errror? I believe what you actually have there is table.put(1, "Hello World"); This really causes the error you have described. I checked it under 1.4 and it behaves exactly as you described, but not with the code you provided.Flashing
I'm migrating android software over to Nokia however it seems that Nokia is a bit more limited, HashTable is using that import @Arno_Geismar.Tenuis
I do use the obfuscator (only when packaging the jad/jar files) . I tried casting it had the same failure . @Honza Zidek , the code does cause the error, I can't even declare generic types as it forces me to use compliance 1.5 !Tenuis
[Solved] Ok, so after changing compiler compliance level to 1.5 then back to 1.4 seemed to fix the issue!, I did compile with table.put(1, "Hello World"); initially and changed my code to what I have posted here and cleaned my project however it must have confused, thanks for all the replies folks! I would upvote @HonzaZidek but you never left a full answer!Tenuis
@Tenuis - my full answer see below, with detailed explanation. Please fix your question so it is clear to other people, otherwise your question causes confusion.Flashing
F
3

In my answer I suppose that your actual code was in fact the following:

Hashtable table = new Hashtable();
table.put(1, "Hello World");

That's the code which causes the error you have described, i.e.

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

The reason is this:

  1. Java 1.4 does not support generics, so the Hashtable simply works with Objects (both as keys as well as values)

  2. Java 1.4 does not support autoboxing, so the code table.put(1, "Hello World") is not automatically autoboxed to table.put(Integer.valueOf(1), "Hello World"). Hence you are trying to call table.put(int, String) which is not compatible with Hashtable.put(Object, Object).

Voila.

If you used Java 1.5+, the call would be autoboxed to table.put(Integer, String)

BTW, do not use new Integer(1), always prefer the static factory method Integer.valueOf(1). You may avoid unnecessary creation of redundant classes. This is what the autoboxing is compiled into. See this: Static factory methods vs Instance (normal) constructors?

Flashing answered 14/7, 2014 at 12:4 Comment(3)
I changed the compliance level to 1.5 then back to 1.4 and it seems to compile fine now with .put(new Integer(1),"Hello World"). Cool thanks for the suggestion!Tenuis
For Java ME I need to use Integer.valueOf("1")Tenuis
Integer.valueOf(String) is not a good alternative to new Integer(int). The conversion from String is even more expensive. If you don't have the Integer.valueOf(int) method, just use new Integer(int).Flashing
D
3

From the error message you mentioned,

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

It is clear that your compiler treats the Integer object as a primitive value just after it is initialized. Namely it applies unboxing immediately. This might have been done for optimiziation in mobile platforms, if I can find a reference for it, I'll update my answer.

Doucette answered 14/7, 2014 at 11:18 Comment(4)
I think Autoboxing is not available in java 1.4. it was introduced in 1.5.Monikamoniker
I do not believe the code the OP put here is the actual code which caused the error. I believe what he had there was table.put(1, "Hello World");, or something like that.Flashing
@HonzaZidek probably that's the case. i searched for unboxing optimization for j2me but couldn't find decent results.Doucette
Let's wait for the OP's answer. I reckon the whole question is just a mistake.Flashing
F
3

In my answer I suppose that your actual code was in fact the following:

Hashtable table = new Hashtable();
table.put(1, "Hello World");

That's the code which causes the error you have described, i.e.

The method put(Object, Object) in the type Hashtable is not applicable for the arguments (int, String)

The reason is this:

  1. Java 1.4 does not support generics, so the Hashtable simply works with Objects (both as keys as well as values)

  2. Java 1.4 does not support autoboxing, so the code table.put(1, "Hello World") is not automatically autoboxed to table.put(Integer.valueOf(1), "Hello World"). Hence you are trying to call table.put(int, String) which is not compatible with Hashtable.put(Object, Object).

Voila.

If you used Java 1.5+, the call would be autoboxed to table.put(Integer, String)

BTW, do not use new Integer(1), always prefer the static factory method Integer.valueOf(1). You may avoid unnecessary creation of redundant classes. This is what the autoboxing is compiled into. See this: Static factory methods vs Instance (normal) constructors?

Flashing answered 14/7, 2014 at 12:4 Comment(3)
I changed the compliance level to 1.5 then back to 1.4 and it seems to compile fine now with .put(new Integer(1),"Hello World"). Cool thanks for the suggestion!Tenuis
For Java ME I need to use Integer.valueOf("1")Tenuis
Integer.valueOf(String) is not a good alternative to new Integer(int). The conversion from String is even more expensive. If you don't have the Integer.valueOf(int) method, just use new Integer(int).Flashing
P
2

Problem with your code is that, as you mentioned, is 1.4 compliance, which makes me think you're compiling for it to be 1.4 compatible. Boxing / unboxing is a feature added in 1.5.

Just for you to confirm what I mean: try compiling your code with javac --source 1.5 --target 1.5, it will compile fine, but try the same with javac --source 1.4 --target 1.4 then it will complain

Prenotion answered 14/7, 2014 at 11:29 Comment(0)
E
0

I ignore which JVM is being used for Java develop in Nokia mobiles (I would assume a Java ME), but indeed in a typical Java SE environment your code should not give an error, but a warning: You have not used the templates to construct the HashTable, so the JVM ust assume your Integer and String are Object class, instead of the real values.

To avoid this warning, that for some reason your IDE reports as an error, use:

Hashtable<Integer, String> table = new Hashtable<Integer, String>();
table.put(new Integer(1),"Hello World");
Eweneck answered 14/7, 2014 at 11:9 Comment(4)
I don't think this is the issue. If his compiler was throwing errors due to Generics, the second case shouldn't work either..Volition
Which second case?? The compiler tells the default template implementation <Object, Object> is not applicable for <Integer, String>. This is however accepted by the standard but there must be a previous cast from Integer and String to Object to being able to call the Hashtable constructor.Eweneck
Why would the compiler tell that -the default template implementation <Object, Object> is not applicable for <Integer, String>. ?. The second case is the one where the code works.Volition
That's why I suspect he's not using a typical JVM. Probably he's using a Java ME, or a specific IDE, that shows the above message, prior to build, even when it's not an error and automatic cast to a parent object is definitely allowed.Eweneck
E
0

As stated previously you probably don't have the autoboxing feature introduced in java 1.5 as you are running on compliance level 1.4. My suggestion is setting your IDEA jdk to 1.4 instead of 1.7 that you are currently using.

Enphytotic answered 14/7, 2014 at 11:56 Comment(0)
C
-1

Integer is an object. int is not an object, it is a primitive. The object Integer wraps the primitive int. The put(Object, Object) method requires two objects, not a primitive and an object.

Commence answered 14/7, 2014 at 11:7 Comment(1)
new Integer(1) is an Object.Baneberry

© 2022 - 2024 — McMap. All rights reserved.