小编典典

我如何获得一个内部类来继承封闭类的泛型?

java

我正在使用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隐藏了类型T

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

我怎样才能使一切正确?


阅读 225

收藏
2020-10-20

共1个答案

小编典典

您可以:

  • <T>TSTNode(即,使其成为非泛型的)中移除类型参数-仍然可以访问external <T>

  • <T>class中的type参数重命名TSTNode为(say)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 :使用地图(而不是列表)

  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] 要记住的一件事:使用EnumMap代替顺序索引

2020-10-20