0

This works:

static class HashMap {

        private final int initialCapacity;
        private final double loadFactor;
        private List<Data<Character, Integer>> [] table;

        public HashMap() {
          this.initialCapacity = 16;
          this.loadFactor = 0.75;
          table = (List<Data<Character, Integer>> [])new Object[initialCapacity];
        }
    }

This doesn't work (gives a generic array creation error):

static class HashMap<K, V> {

    private final int initialCapacity;
    private final double loadFactor;
    private List<Data<K, V>> [] table;

    public HashMap() {
      this.initialCapacity = 16;
      this.loadFactor = 0.75;
      table = (List<Data<K, V>> [])new Object[initialCapacity];
    }
}

How do I get the second version to work?

As you can probably tell, I'm trying to implement a generic HashMap for fun. The Data class is just a simple, custom tuple class that I wrote, and I would like my HashMap to function with any key/value types that the user may provide. The table array is an array of linked lists that contain tuples (basically a hash table). NOTE: The List class here is NOT the built-in Java List class, it is also a class that I WROTE MYSELF!

There are some questions on SO regarding the generic array creation error, but none of them address this kind of scenario. Any ideas are appreciated!

P.S Here's the Data class in case anyone wants to test out the code:

  static class Data<K, V> {
    private final K key;
    private final V value;
    public Data(K key, V value) {
      this.key = key;
      this.value = value;
    }
    public K getKey() {
      return key;
    }
    public V getValue() {
      return value;
    }
    @Override
    public boolean equals(Object obj) {
      if (obj == null)
        return false;
      if (!Data.class.isAssignableFrom(obj.getClass()))
        return false;

      final Data<K, V> b = (Data<K, V>) obj;
      return this.key.equals(b.getKey());
    }
  }
corecase
  • 1,268
  • 5
  • 17
  • 29
  • I was able to get the generic array creation to work using the top answer in [How to create a generic array in Java?](https://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java). Do something similar to that answer (checked, strong typing part). – rgettman Dec 15 '17 at 22:54
  • Hmm, interesting... I'll give it a shot, thanks! – corecase Dec 15 '17 at 22:56
  • @rgettman I'm passing in the K and V type classes into the HashMap constructor, but I'm having trouble using Array.newInstance() to create an array of List> using those parameters. Would you mind sharing your method of accomplishing this? – corecase Dec 16 '17 at 01:34
  • Call `Array.newInstance(List.class, initialCapacity)`, cast it to `List>[]`. You don't need K's or V's class objects. – rgettman Dec 16 '17 at 01:37
  • That worked, thank you! Not sure I understand why it works though, to be honest... I thought the K and V were the issues here, since those are the parameters that are unknown at compile time. – corecase Dec 16 '17 at 01:49
  • 1
    Type erasure occurs on a successful compile; the JVM has no concept of what K and V are. So we just need to create a dynamic array of `List` and cast it to the appropriate type; the compiler will type-check all other uses of the array, provided you used generics there too. – rgettman Dec 16 '17 at 01:52
  • @rgettman: Calling `Array.newInstance()` with a class literal hard-coded at compile-time is silly; just doing `new List[initialCapacity]` does the exact same thing and is simpler. Here the actual component type is known at compile-time, so there is no need for any reflection stuff. – newacct Dec 16 '17 at 15:30
  • @rgettman: The linked question is the wrong duplicate because that question wanted to create an array of a *type variable* type, whereas here they want to create an array of a *parameterized type* -- the solution here is to create an array of the raw type instead. – newacct Dec 16 '17 at 15:35
  • @newacct I was actually trying to understand why we need to use Array.newInstance() in this case, and what you're saying definitely clears things up for me now. And since that's the case this is definitely not a duplicate of the linked question. – corecase Dec 16 '17 at 21:02

0 Answers0