Home > database >  Casting consumer generic type to another type
Casting consumer generic type to another type

Time:09-29

Please first look at my code. I get an error in the BolBFS constructor when I want to create an object:

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

I know I can't cast consumer<T> to consumer\<? extends T>, but I don't know why, and how should I handle this problem?
If I change Node<Identifire, Data> to N, I have another problem in the adj() method in class BFS.

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

This is my code:

BolBFS.java constructor:

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

}

Node.class:

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

CodePudding user response:

The problem is that a Consumer<BolNode> is not a Consumer<Node<String, ChildFlightConsignmentInfo>>, for the same reason that a List<Dog> is not a List<Animal>. More specifically, a Consumer<BolNode> expects that it will always be passed a BolNode, whereas a Consumer<Node<String, ChildFlightConsignmentInfo>> might be passed any subclass of Node<String, ChildFlightConsignmentInfo>.

You have declared a type parameter N extends Node<Identifier, Data> in the BFS class, but then not used it in the constructor parameter types. I would suggest trying:

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