0

To give you a bit of context, I am trying to build from scratch a HashMap using Java.

I have some issues when I am trying to instantiate an array of Nodes (Private class as defined below). I just want to instantiate the array first (in the constructor) and later I will update the same array (in methods not yet implemented).

Please find below the code to replicate the bug and the error message. Why the line this.array = (K[]) new Object[this.size]; works and the line this.buckets = (Node[]) new Object[this.size]; doesn't work?.

Is this achievable in Java or should I completely rethink the logic?

public class MyHashMapTest<K, V> {

    private class Node {
        K key;
        V val;
        Node next;

        Node(K k, V v, Node n) {
            key = k;
            val = v;
            next = n;
        }
    }

    private static final double defaultLoadFactor = 0.75;
    private static final int defaultSize = 16;

    private Node[] buckets;
    private K[] array;

    private int size;
    private int items;
    private double loadFactor;

    public MyHashMapTest() {
        this(defaultSize, defaultLoadFactor);
    }

    public MyHashMapTest(int initialSize) {
        this(initialSize, defaultLoadFactor);
    }

    public MyHashMapTest(int initialSize, double loadFactor) {
        this.size = initialSize;
        this.loadFactor = loadFactor;
        this.items = 0;
        this.array = (K[]) new Object[this.size];
        this.buckets = (Node[]) new Object[this.size];
    }

    public static void main(String[] args) {
        MyHashMapTest<String, String> a = new MyHashMapTest<String, String>();
    }
}

user3577165
  • 85
  • 1
  • 8
  • Does this answer your question? [casting Object array to Integer array error](https://stackoverflow.com/questions/1115230/casting-object-array-to-integer-array-error) – Frank Puffer Dec 04 '19 at 19:28
  • 1
    Thanks for sharing the link, actually I know how to instantiate an array of integers. I am trying to instantiate an array of Nodes (as defined above). I have edited my post to better reflect this. – user3577165 Dec 04 '19 at 19:36
  • 1
    What's wrong with `this.buckets = new Node[this.size];`? – Costi Ciudatu Dec 04 '19 at 19:43
  • The thing is, you can't cast an array of a base type to an array of a derived type. You need to cast each element individually. – Frank Puffer Dec 04 '19 at 19:45
  • I get a compilation error: generic array creation – user3577165 Dec 04 '19 at 19:45
  • Oh, I see. Let me try to answer that properly. – Costi Ciudatu Dec 04 '19 at 19:47
  • 1
    You have to use reflection (specifically [`Array.newInstance`](https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/reflect/Array.html#newInstance%28java.lang.Class,int%29)) to programmatically create a generic array. – Powerlord Dec 04 '19 at 20:02

1 Answers1

1

Your Node class is not static, which means it is bound to an instance of your outer class. You can work around that in two ways.

  1. Create the array using java.lang.reflect.Array:

this.buckets = (Node[]) Array.newInstance(Node.class, this.size);

  1. Make your nested class static (and add generics to it):

private static class Node<A, B> {

You can then define your buckets array of the generic types you need:

private Node<K, V>[] buckets;

And then you can just instantiate your array "normally":

this.buckets = new Node[this.size];
Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92