【问题标题】:Casting consumer generic type to another type将消费者泛型类型转换为另一种类型
【发布时间】:2021-09-29 08:40:27
【问题描述】:

请先看看我的代码。当我想创建一个对象时,我在 BolBFS 构造函数中遇到错误:

Error:
Required type is : Consumer<Node<String, ChildFlightConsignmentInfo>>
Provided type is : Consumer<BolNode>

我知道我不能将consumer&lt;T&gt; 转换为consumer\&lt;? extends T&gt;,但我不知道为什么,我应该如何处理这个问题?
如果我将 Node 更改为 N,我在 BFS 类中的 adj() 方法中会遇到另一个问题。

Error:
Required Set<N>
Provided Provided Set<Node<Identifier, Data>>

这是我的代码:

BolBFS.java 构造函数:

public BolBFS(TraverseDirection dir, BolNode root, Consumer<BolNode> consumeEachBol, Predicate<BolNode> setFlagCondition, Predicate<BolNode> stopCondition) {
    BFS<String, ChildFlightConsignmentInfo, BolNode> bfs =  new BFS<>(dir, root, consumeEachBol, setFlagCondition, stopCondition);
}

BolNode.java:

public class BolNode extends Node<String, ChildFlightConsignmentInfo>

BFS.java:

public class BFS<Identifier, Data, N extends Node<Identifier, Data>> implements Serializable {

    protected TraverseDirection dir;
    protected volatile Queue<Node<Identifier, Data>> nextToVisit;
    protected volatile boolean flag;
    protected volatile Set<Object> visited;
    protected Consumer<Node<Identifier, Data>> consumer;
    protected Predicate<Node<Identifier, Data>> checker;
    protected Predicate<Node<Identifier, Data>> stopCondition;
    protected volatile Map<Object, Node<Identifier, Data>> predecessor;
    protected volatile Map<Integer, Set<Node<Identifier, Data>>> levels;
    protected volatile Map<Object, Set<Object>> adjList;
    protected volatile Map<Object, Node<Identifier, Data>> idMap;

    public BFS(TraverseDirection dir, Node<Identifier, Data> root, Consumer<Node<Identifier, Data>> consumer, Predicate<Node<Identifier, Data>> checker, Predicate<Node<Identifier, Data>> stopCondition) {        this.dir = dir;
        this.flag = false;
        this.checker = checker;
        this.consumer = consumer;
        this.stopCondition = stopCondition;
        this.predecessor = new ConcurrentHashMap<>();
        this.levels = new ConcurrentHashMap<>();
        this.adjList = new ConcurrentHashMap<>();
        this.idMap = new ConcurrentHashMap<>();
        idMap.put(root.getId(), root);
        levels.put(0, Stream.of(root).collect(Collectors.toSet()));
        logic(root, consumer, checker, stopCondition);
    }
    protected Map<TraverseDirection, Set<N>> adj(N node) {
        Map<TraverseDirection, Set<N>> result = new ConcurrentHashMap<>();
        result.put(TraverseDirection.ANY, node.getChild());
        return result;
    }

}

节点类:

public abstract class Node<Identifier, Data> implements Serializable {
    public abstract Set<Node<Identifier, Data>> getChild();
    }

【问题讨论】:

  • 我认为? extends T 的意思是“某物,但从 T 延伸的非常具体的东西”。 A,B,C... 可以匹配 T 如果所有扩展 T,并且它们都可以完全是 T。但是如果你将它转换为 ? 那么它是哪一个可能的匹配?
  • 为什么你的很多字段都是volatile
  • 为什么要声明N extends Node&lt;Identifier, Data&gt;,然后在构造函数参数类型中使用Node&lt;Identifier, Data&gt;
  • @Antoniossss 我说? extends T 发送我的概念,我的意思是从T 延伸,在我的例子中? = BolNodeT = Node
  • 不,T 是 T,BolNode 是 BolNode。 ?是“某事”,即使您当前的情况可以扣除它会是什么。

标签: java casting consumer


【解决方案1】:

问题在于Consumer&lt;BolNode&gt; 不是Consumer&lt;Node&lt;String, ChildFlightConsignmentInfo&gt;&gt;,原因与a List&lt;Dog&gt; is not a List&lt;Animal&gt; 相同。更具体地说,Consumer&lt;BolNode&gt; 期望它总是被传递给 BolNode,而 Consumer&lt;Node&lt;String, ChildFlightConsignmentInfo&gt;&gt; 可能被传递给 Node&lt;String, ChildFlightConsignmentInfo&gt; 的任何子类。

您在BFS 类中声明了一个类型参数N extends Node&lt;Identifier, Data&gt;,但随后没有在构造函数参数类型中使用它。我建议尝试:

public BFS(
    TraverseDirection dir,
    N root,
    Consumer<N> consumer,  // Or Consumer<? super N>
    Predicate<N> checker,  // Or Predicate<? super N>
    Predicate<N> stopCondition) {

【讨论】:

  • @vahidghasemi 请将其编辑到您的问题中。无法在评论中阅读。
  • 我尝试了您的建议,但代码中出现了另一个错误。 (已编辑)我应该在另一篇文章中问我的问题吗?
猜你喜欢
  • 1970-01-01
  • 2012-03-28
  • 2020-12-02
  • 2011-08-09
  • 2015-12-02
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
相关资源
最近更新 更多