When i use this code from another class (I'll post the client if necessary, but in the interest of making a short post:)
I get an ArrayStoreException from line 31.
As I see it: the array is of runtime-type V, the item that should be added to the array should be aswell, or the error should have occured at compiletime, when trying to call pu(K,V) with a wrong value type?
So, what am I not getting? :)

import java.util.Arrays;

public class ResizableMap<K extends Comparable<K>, V> {
        private int N=0;
        private K[] keys;
        private V[] vals;

        @SuppressWarnings("unchecked")
        public ResizableMap() {
                keys = (K[]) new Comparable[1];
                vals = (V[]) new Comparable[1];
        }

        public boolean isEmpty()        { return N==0;  }
        public int size()               { return N;     }

        public void put(K key, V value) {
                if(N == keys.length) resize(2*keys.length);
                int p = rank(key);
                if (key == keys[p]){
                        vals[p] = value;
                        return;
                }

                for(int i=N; i>p; i--) {
                        keys[i] = keys[i-1];
                        vals[i] = vals[i-1];
                }

                keys[p] = key;
                vals[p] = value;
                N++;
        }

        public V getValue(K key){
                if (isEmpty()) return null;
                int i = rank(key);
                if (i < N && keys[i].compareTo(key) == 0) return vals[i];
                return null;
        }

        public K getKey(int i){
                if (i>=N) throw new ArrayIndexOutOfBoundsException(i);
                return keys[i];
        }

        public int rank(K item){
                return rank(item, 0, N-1);
        }

        public int rank(K item, int lo, int hi) {
                if (item == null) return -1;
                if (lo > hi) return lo;
                int half = lo + (hi-lo)/2;
                int cmp = item.compareTo(keys[half]);

                if (cmp < 0) return rank(item, lo, half-1);
                if (cmp > 0) return rank(item, half +1, hi);
                return half;
        }

        private void resize(int cap) {
                @SuppressWarnings("unchecked")
                K[] tmpK = (K[]) new Comparable[cap];
                @SuppressWarnings("unchecked")
                V[] tmpV = (V[]) new Comparable[cap];
                for(int i=0; i<N; i++){
                        tmpK[i] = keys[i];
                        tmpV[i] = vals[i];
                }
                keys = tmpK;
                vals = tmpV;
        }

        //A litte test
        public static void main(String[] args) {
                ResizableMap<Character, Character> rm = new ResizableMap<>();
                f
                for (int i=33; i<122; i++){
                        rm.put((char)i, (char)i);
                }
        }
}

Recommended Answers

All 5 Replies

Maybe it's Character vs char. The generic type is Character, but you try to put a char. Autoboxing will often deal with this kind of thing, but not always, maybe this is one of those times? Try put(new Character(...

Can you make a small complete program that compiles, executes and shows the problem?

James: I doubt it, the main methods actually works perfectly (sorry, probably should have mentioned that or left it out).

Norm: I'm not sure how to recreate it, but I can post the client that causes the problem:
This is the exact error I get:

Exception in thread "main" java.lang.ArrayStoreException: WordTree$Node
at ResizableMap.put(ResizableMap.java:31)
at WordTree$Node.addChild(WordTree.java:35)
at WordTree.put(WordTree.java:18)at WordTree.put(WordTree.java:12)
at WordTree.put(WordTree.java:5)at WordTree.main(WordTree.java:50)

And here is the client:

public class WordTree {
        Node root=null;

        public void put(CharSequence word){
                put(word, root);
        }

        private void put(CharSequence word, Node n){
                if (word.length()==0) return;
                if (n == null){
                        root = new Node(word.charAt(0));
                        put (word.subSequence(1, word.length()-1), root);
                        return;
                }

                if (n.getChild(word.charAt(0)) == null){
                        Node nxt = new Node(word.charAt(0));
                        n.addChild(nxt);
                        put(word.subSequence(1, word.length()-1), nxt);
                        return;
                }
                Node nxt=n.getChild(word.charAt(0));
                put(word.subSequence(0, word.length()-1), nxt);
        }

        public class Node {
                private ResizableMap<Character, Node> children = new ResizableMap<>();
                private Character key;

                public Node(Character c) {
                        key = c;
                }

                public void addChild(Node n){
                        children.put(n.getChar(), n);
                }

                public Character getChar(){
                        return key;
                }

                //returns null if child doesn't exist
                public Node getChild(Character c) {
                        return children.getValue(c);
                }
        }

        public static void main(String[] args){
                WordTree t = new WordTree();
                t.put("lars");
        }
}

I don't get how the Node suddently isn't a Node?

Add a println to show what vals is and what the class of value is.
This will show you why yout get ArrayStoreException.

commented: This should have been the first thing I tried, before even writing on this forum. +2

You sir, are a brilliant man :)
Turns out I made the array like this: vals = (V[]) new Comparable[1];
And of course, the values should not need to be comparable :)
So even though they where of type V, they did not meet the requirements of the array.
Funny that it was even permittet to make the array, when runtime-type V wasn't comparable.

Anyway, thanks a bunch. Both of you.
This really had me startled.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.