Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使BlockingQueue接受多种类型?_Java_Generics_Blockingqueue - Fatal编程技术网

Java 如何使BlockingQueue接受多种类型?

Java 如何使BlockingQueue接受多种类型?,java,generics,blockingqueue,Java,Generics,Blockingqueue,我有classX、classY和classZ。如果X或Y执行特定条件,则应将其放入BlockingQueue。ClassZ只是将它们从队列中取出 我知道创造这样的东西: BlockingQueue<X,Y> BQueue=new ArrayBlockingQueue<X,Y>(length); BlockingQueue BQueue=newarrayblockingqueue(长度); 这是违法的。如何正确设置?最简单的方法是允许阻塞队列接受任何对象类型: Bloc

我有class
X
、class
Y
和class
Z
。如果
X
Y
执行特定条件,则应将其放入
BlockingQueue
。Class
Z
只是将它们从队列中取出

我知道创造这样的东西:

BlockingQueue<X,Y> BQueue=new ArrayBlockingQueue<X,Y>(length);
BlockingQueue BQueue=newarrayblockingqueue(长度);

这是违法的。如何正确设置?

最简单的方法是允许
阻塞队列
接受任何对象类型:

BlockingQueue<Object> q = new ArrayBlockingQueue<>(length);
如果
X
Y
继承自公共类或实现公共接口,请使队列更加具体:

BlockingQueue<XYInterface> q = new ArrayBlockingQueue<>(length);
BlockingQueue q=新的ArrayBlockingQueue(长度);

您可以按照Sasha的建议执行,并使用
阻塞队列
,但我更喜欢将公共功能声明到接口中,然后让每个类处理自己的功能,而不是使用
实例声明:

public interface Common {

    boolean shouldEnqueue();

    void doSomething();

}

public class X implements Common {

    public boolean shouldEnqueue() {
        ...
    }

    public void doSomething() {
        System.out.println("This is X");
    }
}

public class Y implements Common {

    public boolean shouldEnqueue() {
        ...
    }

    public void doSomething() {
        System.out.println("This is Y");
    }
}

public class Producer {

    private final BlockingQueue<Common> queue;

    void maybeEnqueue(Common c) {
        if(c.shouldEnqueue()) {
            queue.add(c);
        }
    }
}

public class Consumer {
    private final BlockingQueue<Common> queue;

    void doSomething() {
        queue.take().doSomething();
    }
}
公共接口公共{
布尔值shouldEnqueue();
无效剂量();
}
公共类X实现了公共类{
公共布尔值shouldEnqueue(){
...
}
公共无效剂量测定法(){
System.out.println(“这是X”);
}
}
公共类Y实现公共类{
公共布尔值shouldEnqueue(){
...
}
公共无效剂量测定法(){
System.out.println(“这是Y”);
}
}
公共级制作人{
私有最终阻塞队列;
void maybeEnqueue(通用c){
if(c.shouldEnqueue()){
添加(c);
}
}
}
公共类消费者{
私有最终阻塞队列;
无效剂量测定法(){
queue.take().doSomething();
}
}

如果(o instanceof X)
非常难看。@PatrickCollins如果
X
不是
Y
的子类,或者反之亦然,它将正常工作。否则,应该创建最一般类型(X或Y)的队列。我认为这个问题表明@prgst的部分存在设计缺陷——他/她需要重新思考他/她的类层次结构,并询问这是否有意义——可能没有。@PatrickCollins有时这并不容易,甚至不可能。假设您有来自不同来源的不同类型的消息,并且只需要一个使用者使用它们。您不能让它们实现公共接口和声明策略,将它们包装在包装类中也不会有帮助:在展开时,您还需要以某种方式发现特定类型。使用命令模式,让对象执行它们自己的处理行为。或者,给他们一个
addConsumer
方法,为他们提供对消费者的引用,然后给他们一个
consumer
方法,该方法调用您刚才添加的消费者上的适当方法。这样做从来没有好的理由。当然,环境会对解决方案产生影响。如果可能的话,这是我更喜欢的。
public interface Common {

    boolean shouldEnqueue();

    void doSomething();

}

public class X implements Common {

    public boolean shouldEnqueue() {
        ...
    }

    public void doSomething() {
        System.out.println("This is X");
    }
}

public class Y implements Common {

    public boolean shouldEnqueue() {
        ...
    }

    public void doSomething() {
        System.out.println("This is Y");
    }
}

public class Producer {

    private final BlockingQueue<Common> queue;

    void maybeEnqueue(Common c) {
        if(c.shouldEnqueue()) {
            queue.add(c);
        }
    }
}

public class Consumer {
    private final BlockingQueue<Common> queue;

    void doSomething() {
        queue.take().doSomething();
    }
}