HashMap and int as key

221,442

Solution 1

You can't use a primitive because HashMap use object internally for the key. So you can only use an object that inherits from Object (that is any object).

That is the function put() in HashMap and as you can see it uses Object for K:

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

The expression "k = e.key" should make it clear.

I suggest to use a wrapper like Integer and autoboxing.

Solution 2

Use Integer instead.

HashMap<Integer, MyObject> myMap = new HashMap<Integer, MyObject>();

Java will automatically autobox your int primitive values to Integer objects.

Read more about autoboxing from Oracle Java documentations.

Solution 3

For everybody who codes Java for Android devices and ends up here: use SparseArray for better performance;

private final SparseArray<myObject> myMap = new SparseArray<myObject>();

with this you can use int instead of Integer like;

int newPos = 3;

myMap.put(newPos, newObject);
myMap.get(newPos);

Solution 4

You may try to use Trove http://trove.starlight-systems.com/
TIntObjectHashMap is probably what you are looking for.

Solution 5

HashMap does not allow primitive data types as arguments. It can only accept objects so

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

will not work.

You have to change the declaration to

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

so even when you do the following

myMap.put(2,myObject);

The primitive data type is autoboxed to an Integer object.

8 (int) === boxing ===> 8 (Integer)

You can read more on autoboxing here http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

Share:
221,442

Related videos on Youtube

MrD
Author by

MrD

PhD Machine Learning &amp; Bioinformatics, Manchester University (In progress...) MRes Advanced Computer Science, Manchester University BSc Computer Science, Sheffield University Probably programming in an airport...

Updated on April 17, 2022

Comments

  • MrD
    MrD about 2 years

    I am trying to build a HashMap which will have integer as keys and objects as values.

    My syntax is:

    HashMap<int, myObject> myMap = new HashMap<int, myObject>();
    

    However, the error returned is - Syntax error on token "int", Dimensions expected after this token - I don't understand why I should add a dimension (ie: making the int into an array) since I only need to store a digit as key.

    What could I do?

    Thanks in advance! :)

    • Menno
      Menno about 11 years
      HashMap doesn't handle primitives, just objects.
    • cyroxx
      cyroxx about 11 years
      Related SO question, but with int being the value, not the key.
    • Hot Licks
      Hot Licks about 11 years
      Use Integer instead.
    • FoxDonut
      FoxDonut almost 3 years
      Long story short, you must use an Integer - but you can add keys as if you it would allow you to use an int. Primitives aren't allowed, but the Integer class will handle primitive values assigned to the map.
  • Adam Gent
    Adam Gent about 11 years
    He should also not name a class myObject
  • gaborsch
    gaborsch about 11 years
    @AdamGent Correct. All class names should start with capitals, I corrected the recommended code.
  • Adam Gent
    Adam Gent about 11 years
    I know you know :) I just want to make sure the OP knows/learns. For all I know he could have been putting a variable name in the type parameter.
  • franki3xe
    franki3xe about 11 years
    I have writen HashMap<Integer, MyObject> myMap = new HashMap<Integer, MyObject>(); but displaying make my problem with > and < to display good answer
  • Adam Gent
    Adam Gent about 11 years
    I know its painful to type but I was trying to save you from immediate -1. I unlike others comment before penalizing (I did not -1 you).
  • TpoM6oH
    TpoM6oH about 10 years
    Remember that SparseArray is slower than hashmap, but more memory efficient. So, don't use it on large data sets.
  • Snake
    Snake over 9 years
    How is SparseArray used for better performance while it is slower? Which one to use in my android game
  • Noah Huppert
    Noah Huppert about 9 years
    Just a quick little note, it is better to use ArrayMap or SimpleArrayMap on Android to save memory and increase performance(More information)
  • Jon
    Jon over 8 years
    @Snake SparseArray If you allocate a bunch of memory boxing and unboxing ints as you would with a HashMap, the vm will need to pause execution for garbage collection sooner. This is important if you are trying to do something frequently and quickly.
  • Vladimir Petrakovich
    Vladimir Petrakovich over 7 years
    Remember that complexity of insertion into SparseArray is O(n) (HashMap has O(1)). It is important when number of elements is large. Insertion into beginning of such array is much slower.
  • TT--
    TT-- over 6 years
    SparseArray "is generally slower than a traditional HashMap, since lookups require a binary search and adds and removes require inserting and deleting entries in the array". @Snake refer to developer.android.com/reference/android/util/SparseArray.htm‌​l and stackoverflow.com/questions/25560629/sparsearray-vs-hashmap
  • Yoory N.
    Yoory N. over 6 years
    No, the main reason for not allowing primitive types is type erasure in Java, that effectively turns Map<Integer, String> into Map<Object, Object> during compilation. BTW, there is IdentityHashMap that uses == operator for equality check, that still doesn't allow primitive types.
  • john16384
    john16384 over 6 years
    Be careful with this, the hash value of an array is not related to its contents, so two arrays with the same content can hash to a different value making it a very poor key.
  • M.kazem Akhgary
    M.kazem Akhgary over 5 years
    @VladimirPetrakovich inserting to end of SparseArray is O(1) if you use append (only usable when keys are added in increasing order), if you use put it takes O(log n) best case (insert at end) and O(n log n) worst case (insert at start). also delete will take O(log n) time because it will only mark found entries as deleted instead of actually deleting them until gc occurs (when you try to read items)
  • Vladimir Petrakovich
    Vladimir Petrakovich over 5 years
    @M.kazemAkhgary Not exactly. put() takes O(n) (not n log n) for insertion at start because it finds position and then shifts all following elements. delete() itself indeed takes O(log n), but the next insertion or iterating through elements after delete will require a garbage collection that takes O(n).
  • Evgeniy Berezovsky
    Evgeniy Berezovsky over 3 years
    I'm considering using Trove - why do you believe it is unreliable?
  • Alex
    Alex over 3 years
    When I tried to find the best library related to the given problem, I had come across on some articles about trove's bugs and as this isn't supported anymore, I decided to not use it. But now, meeting more and more people using it in very big companies, I wouldn't consider it as a such bad choice, as it naturally tested so to say (also taking into account that I cannot find those articles about bugs now), but my self would rather use Eclipse collections.
  • Evgeniy Berezovsky
    Evgeniy Berezovsky over 3 years
    I see. In the meantime, I have found (and added as an answer) the primitive collections included in the Netty library
  • Reza Heidari
    Reza Heidari about 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.