1

I'm trying to implement a trie in Java. When I test if my method "insert" works, I got the error below.

Exception in thread "main" java.lang.ClassCastException: 
class [Ljava.lang.Object; cannot be cast to class [LTrie$TreeNode; ([Ljava.lang.Object; 
is in module java.base of loader 'bootstrap'; [LTrie$TreeNode; is in unnamed module of loader 'app')
at Trie.insert(Trie.java:36)
at Trie.main(Trie.java:47)

I also went through some similar questions but still can't figure it out. I'm wondering why we can't cast the type from Object to TreeNode[] array.

My code is as follows. I know using dataIndexedCharMap by array wasted a lot of memory (HashTable or BST would be a better way), but I'm just trying to compare the memory and efficiency of these three methods but got some trouble.

class Trie {
    private static final int R = 128;
    public TreeNode root;

    private static class TreeNode {
        private boolean isKey;
        private dataIndexedCharMap next;
        private TreeNode(boolean b, int R) {
            isKey = b;
            next = new dataIndexedCharMap<TreeNode>(R);
        }
    }

    public static class dataIndexedCharMap<V> {
        private V[] items;
        public dataIndexedCharMap(int R) {
            items = (V[]) new Object[R];
        }
    }

    /** Initialize your data structure here. */
    public Trie() {
        root = new TreeNode(false, R);
    }

    /** Inserts a word into the trie. */
    public void insert(String word) {
        TreeNode curr = root;
        for (int i = 0; i < word.length(); i++) {
            TreeNode[] array = (TreeNode[]) curr.next.items;
            array[word.charAt(i)] = new TreeNode(false, R);
            curr = array[word.charAt(i)];
            if (i == word.length() - 1) {
                curr.isKey = true;
            }
        }
    }

    public static void main(String[] args) {
        Trie obj = new Trie();
        obj.insert("apple");
    } 
}
user13827546
  • 13
  • 1
  • 1
  • 4
  • Have you tried this private dataIndexedCharMap next; – Sabareesh Muralidharan Jun 28 '20 at 06:14
  • What do you need `V` for? Don't you always want a `new TreeNode[R]` ? – Thilo Jun 28 '20 at 06:18
  • @SabareeshMuralidharan Yes, but same issue happens – user13827546 Jun 28 '20 at 06:27
  • @Thilo I've also tried it. When I replace V with TreeNode and not use casting. The IntelliJ told me Type parameter 'TreeNode' cannot be instantiated directly. That's why I use the generic type. – user13827546 Jun 28 '20 at 06:30
  • How is TreeNode a type parameter? You are doing `new TreeNode()` in there. `TreeNode` has to be a class, not a type parameter for that to work. Show the whole code. But you are right, arrays need to know their runtime type, you cannot instantiate them with an (erased) type parameter. You could keep it an `Object[]` and remove the cast, only cast the individual objects inside when you pull them out of the array. – Thilo Jun 28 '20 at 06:45
  • 1
    By the way, you should follow the Java Naming Conventions: variabele names and method names should be written in camelCase, and class names in PascalCase. So `dataIndexedCharMap` should be `DataIndexedCharMap` and `R` should be `r`. – MC Emperor Jun 28 '20 at 07:28

1 Answers1

1

From your code it looks like dataIndexedCharMap is always going to have items of type TreeNode. In that case, there is no need to create an object array and cast it to TreeNode. You can create TreeNode[] array instead of Object[] array and remove all the generics that you have added.

public static class dataIndexedCharMap {
    private TreeNode[] items;
    public dataIndexedCharMap(int R) {
        items =  new TreeNode[R];
    }
}
Asmat K
  • 121
  • 1
  • 10
  • 1
    Great solution, thanks! But I'm still curious why my previous work fails. Why we can't cast the object[ ] array into the array where each element is a TreeNode – user13827546 Jun 28 '20 at 07:17
  • 1
    Whenever you are downcasting, you need to be sure that the object that is being downcasted is actually an instanceOf the object to which you are downcasting. In your case the array of Object is getting cast to array of TreeNode. Since this does not satisfy the above condition, you get a ClassCastException. To understand better,you can check https://stackoverflow.com/questions/4862960/explicit-casting-from-super-class-to-subclass – Asmat K Jun 28 '20 at 07:32