0

When I use MapEntry[] entry = (MapEntry[]) new Object[capacity],

it tells me java.lang.ClassCastException.

How can this happen? I am confused about this. (Since it seems I should do the casting because it's generic)

I found some tutorial and they were using like this:

 table = new Entry[capacity];

(http://www.javamadesoeasy.com/2015/02/hashmap-custom-implementation.html)

it did not even do the casting.

My codes are below.

public class MyHashMap<K, V> {
    private class MapEntry {
        K key;
        V value;
        MapEntry next;
        MapEntry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    private int size = 0;
    private int capacity;
    MapEntry[] entry;

    @SuppressWarnings("unchecked")
    MyHashMap() {
        capacity = 10;
        entry =  (MapEntry[]) new Object[capacity];
    }

    @SuppressWarnings("unchecked")
    MyHashMap(int capacity) {
        entry =  (MapEntry[]) new Object[capacity];
    }

    public void put(K key, V value) {
        int hash = hashCode(key);
        MapEntry newNode = new MapEntry(key, value);
        if (entry[hash % capacity] == null) {
            entry[hash % capacity] = newNode;
        } else {
            if (key == entry[hash % capacity].key) {
                entry[hash % capacity].value = value;
            } else {
                MapEntry nextNode = entry[hash % capacity].next;
                while (nextNode != null) {
                    if (key == nextNode.key) {
                        nextNode.value = value;
                        return;
                    }
                    nextNode = nextNode.next;
                }
                nextNode = newNode;
            }
        }
    }

    public V get(K key) {
        int hash = hashCode(key);
        MapEntry node = entry[hash % capacity];
        if (node == null) {
            return null;
        }

        if (node.key == key) {
            return node.value;
        }

        while (key != node.key) {
            node = node.next;
            if (node.key == key) {
                return node.value;
            }
        }
        return null;
    }

    public boolean contains(K key) {
        return get(key) != null;
    }

    public int size() {
        return size;
    }

    public void remove(K key) {
        int hash = hashCode(key);
        MapEntry node = entry[hash % capacity];
        if (node == null) return;
        if (key == node.key) {
            entry[hash % capacity] = node.next;
        }

        MapEntry pre = node;
        while (key != node.key) {
            node = node.next;
            if (key == node.key) {
                pre.next = node.next;
                return;
            }
            pre = pre.next;
        }
    }

    private int hashCode(K key) {
        return Math.abs(key.hashCode());
    }

    public void display(){
       for(int i = 0; i < capacity; i++){
           if(entry[i] != null){
                MapEntry node = entry[i];
                while(node != null){
                    System.out.print("{" + node.key + "=" + node.value + "}" + " ");
                    node = node.next;
                }
           }
       }
    }

    public static void main(String[] args) {
        MyHashMap<Integer, Integer> hashMapCustom = new MyHashMap<Integer, Integer>();
        hashMapCustom.put(21, 12);
        hashMapCustom.put(25, 121);
        hashMapCustom.put(30, 151);
        hashMapCustom.put(33, 15);
        hashMapCustom.put(35, 89);

        System.out.println("value corresponding to key 21="
                     + hashMapCustom.get(21));
        System.out.println("value corresponding to key 51="
                     + hashMapCustom.get(51));

        System.out.print("Displaying : ");
        hashMapCustom.display();
        System.out.print("Displaying : ");
        hashMapCustom.display();
    }
}
OneCricketeer
  • 126,858
  • 14
  • 92
  • 185
  • 4
    Why can't you just do `MapEntry[] entry = new MapEntry[capacity]`. You are getting the error because not all `Object` are of the class `MapEntry` – OneCricketeer Mar 12 '16 at 19:32
  • Cricket is right. What if you try to cast a `String` to a `MapEntry` for example. Do you think it will work? – Yassin Hajaj Mar 12 '16 at 19:36
  • but if I use MapEntry[] entry = new MapEntry[capacity], it said cannot create a generic array – Renfei Wang Mar 12 '16 at 21:02

2 Answers2

0

You can't convert a class of an array by just casting that's yhe reason you get ClassCastException. You should use

`Arrays.copyof ().`
CustomType[]ca=Arrays.copyOf(array,array.length,CustomType[].class);
udakarajd
  • 114
  • 10
0

I have figured out how this work.

(Creation of array whose component type is either a type parameter, a concrete parameterized type or a bounded wildcard parameterized type, is type-unsafe.)

    entry =  (MapEntry[]) Array.newInstance(MapEntry.class, capacity);

In this way, there can be no errors.

There is another question with good solution. How to create a generic array in Java?

Community
  • 1
  • 1