我正在使用Java 6。

我无法让内部类使用与其包含的类相同的泛型类。目前我有

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;
        }
    }
}

现在我得到警告



如果我从内部类中删除类型参数(即,从<T>行中删除protected class TSTNode<T>),则在relatives = new TSTNode[4]行上会出现编译错误。

我怎样才能使一切正确?

最佳答案

您可以:

  • <T>中删除TSTNode类型参数(即使其成为非泛型)-仍然可以访问外部<T>
  • 重命名<T>类中的TSTNode类型参数为U

  • [更新]

    下面是四种重写代码的方法。它们全部编译。我认为您应该考虑使用EnumMap(请参见下面的版本4)。

    版本1 :在内部类中使用一个不同名称的type参数。您需要使用列表而不是数组。
      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
        }
      }
    

    版本2 :从封闭类继承T
      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);
        }
      }
    

    版本3 :使用 map (而不是列表)
      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);
        }
      }
    }
    

    版本4 :将索引定义为枚举+使用EnunMap(而不是哈希图)
      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);
        }
      }
    

    [更新2]
    要记住的一件事:Use EnumMap instead of ordinal indexing

    09-15 18:18