I'm using Java 6.
I'm having trouble getting my inner class to use the same generic class as its enclosing class. Currently I have
public class TernarySearchTree < T > { ... protected class TSTNode < T > { // index values for accessing relatives array protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected TSTNode < T > [] relatives; private T data; protected TSTNode(char splitchar, TSTNode < T > parent) { this.splitchar = splitchar; relatives = new TSTNode[4]; relatives[PARENT] = parent; } } }
Right now I get the warning
The type parameter T is hiding the type T
If I remove the type parameter from the inner class (i.e. remove the <T>
from teh protected class TSTNode<T>
line), then I get a compile error on the line relatives = new TSTNode[4]
.
How can I make everything right?
You cannot inherit a generic type. // class Derived20 : T {}// NO!
Inner classesA inner class declared in the same outer class (or in its descendant) can inherit another inner class.
Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.
Yes you can do it.
You can either:
remove the <T>
type parameter from TSTNode
(i.e., make it non-generic) - it will still have access to the outer <T>
.
rename the <T>
type parameter in class TSTNode
to (say) U
.
[UPDATE]
Below are four different ways to rewrite your code. All of them compile. I think you should consider the use of an EnumMap
(see Version 4, below).
Version 1: use a differenly named type parameter in the inner class. you need to use a List instead of an array.
public class TernarySearchTree<T> { protected class TSTNode<U> { // index values for accessing relatives array: protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected List<TSTNode<U>> relatives; private U data; protected TSTNode(char splitchar, TSTNode<U> parent) { this.splitchar = splitchar; relatives = new ArrayList<TSTNode<U>>(); for (int i = 0; i < HIKID; ++i) { // Allocate 4 slots in relatives relatives.add(null); } relatives.set(PARENT, parent); } } private TSTNode<T> node; // When you use it, pass T as U public TernarySearchTree() { node = new TSTNode<T>(',', null); // When you use it, pass T as U } }
Version 2: inherit T from enclosing class
public class TernarySearchTree<T> { protected class TSTNode { // index values for accessing relatives array: protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected List<TSTNode> relatives; private T data; protected TSTNode(char splitchar, TSTNode parent) { this.splitchar = splitchar; relatives = new ArrayList<TSTNode>(); for (int i = 0; i < HIKID; ++i) { // Allocate 4 slots in relatives relatives.add(null); } relatives.set(PARENT, parent); } } private TSTNode node; public TernarySearchTree() { node = new TSTNode(',', null); } }
Version 3: use a Map (instead of a List)
public class TernarySearchTree<T> { protected class TSTNode { // index values for accessing relatives array: protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected Map<Integer, TSTNode> relatives; private T data; protected TSTNode(char splitchar, TSTNode parent) { this.splitchar = splitchar; // Create a hash map. No need to pre-allocate! relatives = new HashMap<Integer, TSTNode>(); relatives.put(PARENT, parent); // set -> put } } private TSTNode node; public TernarySearchTree() { node = new TSTNode(',', null); } } }
Version 4: define the indices as an enum + use an EnunMap (instead of a hash map)
public class TernarySearchTree<T> { protected static enum Index { PARENT, LOKID, EQKID, HIKID; } protected class TSTNode { protected char splitchar; protected EnumMap<Index, TSTNode> relatives; private T data; protected TSTNode(char splitchar, TSTNode parent) { this.splitchar = splitchar; // Create an EnumMap. relatives = new EnumMap<Index, TSTNode>(Index.class); relatives.put(Index.PARENT, parent); } } private TSTNode node; public TernarySearchTree() { node = new TSTNode(',', null); } }
[Update 2] One thing to keep in mind: Use EnumMap instead of ordinal indexing
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With