Java泛型:匹配参数的类型

Java泛型:匹配参数的类型,java,generics,types,parameters,Java,Generics,Types,Parameters,我如何修改它,使生成的集合(newNodes)与传入的集合(nodes)的类型相同 public void集合节点(集合节点){ 集合newNodes=newtreeset(); 用于(节点信息ni:节点){ 添加(ni.clone()); } } 我怀疑这有点像 public void setNodes(<T extends Collection<NodeInfo>> nodes) { Collection<NodeInfo> newNodes =

我如何修改它,使生成的集合(newNodes)与传入的集合(nodes)的类型相同

public void集合节点(集合节点){
集合newNodes=newtreeset();
用于(节点信息ni:节点){
添加(ni.clone());
}
}
我怀疑这有点像

public void setNodes(<T extends Collection<NodeInfo>> nodes) {
    Collection<NodeInfo> newNodes = new T<NodeInfo>()
public void集合节点(节点){
集合newNodes=newt()

这是可能的吗?

不幸的是,您无法在Java中执行
new T
:因为泛型是通过类型擦除在Java中实现的,所以类型参数提供的类型信息只是静态可用的信息,即在运行时不再可用。因此Java不允许泛型创建对象(参见)

或者,您可以使用:

  • 类型标记,即使用
    对象作为参数,使类型在运行时可用
  • 如果您能够在其他地方创建合适的集合,请使用签名
    void setNodes(集合节点,集合新节点)
  • 如果合适,请使用标准集合实现,例如
    ArrayList
  • 深度克隆
    节点
    ,例如使用:

    克隆人克隆人=新克隆人()

    @SuppressWarnings(“未选中”)
    Collection newNodes=cloner.deepClone(节点);


不幸的是,您无法在Java中执行
new T
:由于泛型是通过类型擦除在Java中实现的,因此类型参数提供的类型信息只是静态可用的信息,即在运行时不再可用。因此Java不允许泛型创建对象(参见)

或者,您可以使用:

  • 类型标记,即使用
    对象作为参数,使类型在运行时可用
  • 如果您能够在其他地方创建合适的集合,请使用签名
    void setNodes(集合节点,集合新节点)
  • 如果合适,请使用标准集合实现,例如
    ArrayList
  • 深度克隆
    节点
    ,例如使用:

    克隆人克隆人=新克隆人()

    @SuppressWarnings(“未选中”)
    Collection newNodes=cloner.deepClone(节点);


关闭,但没有雪茄。如果我了解您想要做什么,您的方法应该如下所示:

public <T extends NodeInfo> void setNodes(Collection<T> nodes) {
    Collection<T> newNodes = new TreeSet<T>();
    for(T t : nodes) {
        newNodes.add(t);
    }
}
public void集合节点(集合节点){
集合newNodes=newtreeset();
对于(T:节点){
newNodes.add(t);
}
}

关闭,但不要抽雪茄。如果我了解您想要做什么,您的方法应该如下所示:

public <T extends NodeInfo> void setNodes(Collection<T> nodes) {
    Collection<T> newNodes = new TreeSet<T>();
    for(T t : nodes) {
        newNodes.add(t);
    }
}
public void集合节点(集合节点){
集合newNodes=newtreeset();
对于(T:节点){
newNodes.add(t);
}
}

不幸的是,这是不可能的,因为您是用Java编写的。如果您需要这种效果,您有以下几种选择:

如果您试图针对特定类型的集合进行优化,您可以使用
instanceof
检查来检测它(例如,Guava库经常这样做来检测不可变的集合,并专门处理它们)

如果您确实只需要填充一个集合,您可以要求调用方提供一个集合

public <C extends Collection<NodeInfo>> void setNodes(C nodes, C newNodes) {
  for (NodeInfo ni : nodes) {
    newNodes.add(ni);
  }
}
公共void集合节点(C节点,C新节点){
用于(节点信息ni:节点){
newNodes.add(ni);
}
}
如果需要按需生成任意数量的这些集合,则可以定义factory接口并使调用方提供其实例:

interface Factory<C extends Collection<NodeInfo>> {
  C newCollection();
}

public <C extends Collection<NodeInfo>> void setNodes(C nodes, Factory<C> factory) {
  C newNodes = factory.newCollection();
  for (NodeInfo ni : nodes) {
    newNodes.add(ni);
  }
}
接口工厂{
C newCollection();
}
公共void集合节点(C节点,工厂){
C newNodes=factory.newCollection();
用于(节点信息ni:节点){
newNodes.add(ni);
}
}

不幸的是,这是不可能的,因为您是用Java编写的。如果您需要这种效果,您有以下几种选择:

如果您试图针对特定类型的集合进行优化,您可以使用
instanceof
检查来检测它(例如,Guava库经常这样做来检测不可变的集合,并专门处理它们)

如果您确实只需要填充一个集合,您可以要求调用方提供一个集合

public <C extends Collection<NodeInfo>> void setNodes(C nodes, C newNodes) {
  for (NodeInfo ni : nodes) {
    newNodes.add(ni);
  }
}
公共void集合节点(C节点,C新节点){
用于(节点信息ni:节点){
newNodes.add(ni);
}
}
如果需要按需生成任意数量的这些集合,则可以定义factory接口并使调用方提供其实例:

interface Factory<C extends Collection<NodeInfo>> {
  C newCollection();
}

public <C extends Collection<NodeInfo>> void setNodes(C nodes, Factory<C> factory) {
  C newNodes = factory.newCollection();
  for (NodeInfo ni : nodes) {
    newNodes.add(ni);
  }
}
接口工厂{
C newCollection();
}
公共void集合节点(C节点,工厂){
C newNodes=factory.newCollection();
用于(节点信息ni:节点){
newNodes.add(ni);
}
}

请注意,JDK中的许多
集合
实现本身实现了
可克隆性

public Collection<NodeInfo> setNodes(Collection<NodeInfo> nodes) throws CloneNotSupportedException {
    Collection<NodeInfo) newNodes;

    if (nodes instanceof Cloneable) 
        newNodes = (Collection<NodeInfo>) newNodes.clone();
    else
        // Fallback in case we have a non-cloneable collection
        newNodes = new TreeSet<NodeInfo>();

    newNodes.clear();
    for (NodeInfo ni: nodes) {
        newNodes.add(ni.clone());
    }
    return newNodes;
}
公共集合集合集合节点(集合节点)抛出CloneNotSupportedException{

Collection请注意,JDK中的许多
Collection
实现本身都实现了
可克隆性

public Collection<NodeInfo> setNodes(Collection<NodeInfo> nodes) throws CloneNotSupportedException {
    Collection<NodeInfo) newNodes;

    if (nodes instanceof Cloneable) 
        newNodes = (Collection<NodeInfo>) newNodes.clone();
    else
        // Fallback in case we have a non-cloneable collection
        newNodes = new TreeSet<NodeInfo>();

    newNodes.clear();
    for (NodeInfo ni: nodes) {
        newNodes.add(ni.clone());
    }
    return newNodes;
}
公共集合集合集合节点(集合节点)抛出CloneNotSupportedException{

CollectionIt不可能,也可能不可取。顺便说一句,您的示例没有做任何有用的事情:它填充本地树集并立即丢弃它。我应该添加一些省略号或描述…此方法当前接收集合,生成深度副本,并一次性将本地成员设置为副本呜呜。在for循环之后,但在赋值之前,有更多的处理,我忽略了,很抱歉误传。这不可能,而且可能不可取。顺便说一句,你的示例没有做任何有用的事情:它填充本地树集并立即丢弃。我应该添加一些省略号或描述……这种方法目前在一个学院学习