【问题标题】:java "generic generic type"java“泛型泛型类型”
【发布时间】:2014-03-25 06:57:58
【问题描述】:

在我的申请中,我有一个董事会。板由单元组成。每个单元格都有一个 int 值。 有几种类型的板可以扩展板。 每种类型的 Board 都会以不同的方式表示单元格。例如,一个人会使用一个列表,而另一个人会使用一个树。

所以这是尝试过的:

public abstract class Board<T> {
    T<Cell> cells;  //error - The type T is not generic; it cannot be parameterized with arguments <Cell>

    protected abstract void setValues(T<Integer> values);
}

不幸的是,我不能使 T 成为泛型类型。 我该如何实现?

【问题讨论】:

  • 也许在你的班级签名中加入T extends Collection?这样你就可以使用ListTree?对我的建议不太自信,如有必要,我想批评。
  • 您能否提供一个您将用于T 的类的示例?通常,您只需将参数化类型嵌套在Board 的泛型声明中,但是拥有一个不受限制的T 参数并期望它是泛型的没有意义;如果TInteger 怎么办?此外,在这种情况下,仅子类化 Board 会比在其上使用泛型参数更有意义吗?毕竟,如果客户为他们提供代理,就必须意识到这些差异。
  • 勾画两个用例真的很有帮助。特别是您打算如何使用setValues 方法,板应如何在内部访问其cells,以及T 可以是什么类型(当您说“树”时,您的意思是TreeSet?如果它总是是Collection,那么这是相当微不足道的......)
  • @chrylis 如何让T 成为通用的?
  • 您是否考虑过使用支持更高种类的Scala?毕竟,你似乎才刚刚起步。

标签: java generics


【解决方案1】:

我发现你的方法太复杂了。 Peter.petrov 接近我将要做的事情。

如果 List 和 Tree (TreeSet) 是您所需要的,它们都实现了接口 Collection,那么为什么不使用它呢?除了添加、删除、迭代之外,您还需要其他任何东西吗?

Collection (Javadoc)

所以你的班级可以看起来(我添加了一点 Java8 功能)

public abstract class Board {
    Collection<Cell> cells;  

    // Don't need to be abstract
    protected void setValues(Collection<Integer> values) {
        Stream<Cell> transformed = values.stream().map(Cell::new);
        cells.addAll(transformed.collect(Collectors.toList()));
    }
}

class Cell {
    private Integer value;

    Cell(Integer value) {
        this.value = value;
    }
}

如果您需要(出于某种原因需要额外的东西,请扩展此类并实现/覆盖将执行特殊行为的方法)。希望我能帮上忙,但我真的没有看到您的示例的用例。

【讨论】:

  • 你能解释一下setVaues中的代码吗?另外,如果cells 是List 而values 是Tree,会发生什么?
  • 第一行是新的 (Java8) 并将集合(可能是 List、Set 等)转换为 Stream,然后从 Integer 映射到 Cell。在 Java8 之前,您将需要 For-each 循环和匿名函数实现,但在 Java8 中,您可以轻松使用 CONSTRUCTOR REFERENCE ,它将获取每个元素(即字符串)并查找带有字符串和合同 Cell 对象的构造函数。 Map 返回 Stream ,您将其转换为 Collection (这将是您的内部表示。
  • 关于问题的后半部分。没有树这样的东西。有树集。它将以相同的方式工作(如果您从 Collection 切换到 TreeSet.
【解决方案2】:

你需要有类似的东西:

public abstract class Board<T extends OtherGenericClass<TT>, TT> {
    T cells;
    public Board(T cells) {
        this.cells = cells;
    }
    protected abstract void setValues(T<Integer> values);

    public static void main(String[] args) {
        Cell<Integer> cells = new Cell<Integer>();
        Board<Cell<Integer>,Integer> board = new Board<Cell<Integer>,Integer>(cells);
    }
}

这似乎不是你想要的……我想你宁愿有这个:

public abstract class Board<T> {
    Cell<T>[] cells;
    public Board(Cell<T>[] cells) {
        this.cells = cells;
    }
}

使用Cell 类:

public abstract class Cell<T> {
    T cellValue;
    public Cell(T cellValue) {
        return cellValue;
    }
}

【讨论】:

  • public abstract class Board&lt;T extends OtherGenericClass&lt;TT&gt;, TT&gt; 给了我完全相同的错误
  • @AmitK 抱歉我忘记更改部分代码 =p 再次检查
  • 这似乎对我处理不同的细胞结构没有帮助
  • @AmitK 你读过我的建议吗?第一个是拼凑尝试使您尝试过的工作,第二个是处理可以包含Generic 对象的Cells 的更好方法。
【解决方案3】:

我认为这里没有太多需要使用泛型。

public abstract class Board {
    Holder<Cell> cells;   

    protected abstract void setValues(Integer[] values);
}

现在让您的 List 和 Tree 实现/扩展 Holder。
您可以拥有 2 个类 ListHolder 和 TreeHolder,它们都持有
单元格,但一个由列表支持,另一个由树支持。

实际上,setValues 可能更有意义
ListHolder 和 TreeHolder 都实现的 Holder 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多