如何在Java中从动态源生成对象流?
我正在尝试解决一个问题,看起来用Java是不可能的 我有一些调用processObject(SomeObject SomeObject)的代码和处理它的方法。我正试图封装这整件事,并希望得到一些对象流 下面是我的示例程序:如何在Java中从动态源生成对象流?,java,java-stream,Java,Java Stream,我正在尝试解决一个问题,看起来用Java是不可能的 我有一些调用processObject(SomeObject SomeObject)的代码和处理它的方法。我正试图封装这整件事,并希望得到一些对象流 下面是我的示例程序: import java.util.stream.Stream; public class ProcessObject { public static void main(String[] args) { int i = 0; Pro
import java.util.stream.Stream;
public class ProcessObject {
public static void main(String[] args) {
int i = 0;
ProcessObject processObject = new ProcessObject();
while (true) {
processObject.processObject(new SomeObject("Hello " + i++));
}
}
public void processObject(SomeObject someObject) {
System.out.println(someObject);
}
//TODO
public Stream<SomeObject> getStream(){
//Producer here should wait and produce Objects as soon as
//they become available like "processObject" method.
return Stream.generate(() -> new SomeObject("Hello "));
}
}
class SomeObject {
public String name;
public SomeObject(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
import java.util.stream.stream;
公共类ProcessObject{
公共静态void main(字符串[]args){
int i=0;
ProcessObject ProcessObject=新的ProcessObject();
while(true){
processObject.processObject(新的SomeObject(“Hello”+i++”);
}
}
public void processObject(SomeObject SomeObject){
System.out.println(someObject);
}
//待办事项
公共流getStream(){
//此处的生产者应等待并尽快生成对象
//它们变得像“processObject”方法一样可用。
返回Stream.generate(()->newsomeobject(“Hello”);
}
}
类对象{
公共字符串名称;
公共对象(字符串名称){
this.name=名称;
}
@凌驾
公共字符串toString(){
返回名称;
}
}
静态main方法继续生成someobject,并调用processObject方法来处理它们,然后打印它们。所以,一切都很好
我想创建SomeObject的流,这样我就不用调用方法来处理它们,而是使用流来处理它们,类似这样:
公共流getStream()
现在有了Java8或Java9,就有了可用的流。但是把不可变特征的条件从生成它们的源中放出来
如何创建一个流,然后在元素像真正的管道一样可用时向流中添加元素?
我曾想过使用BlockingQueue并在流生成方法中使用它作为类似BlockingQueue.take()的生产者,但它从未编译过。这里的问题是不能在lambda表达式中变异局部变量
I
,不是吗?因为lambda基本上是一个匿名的内部类,所以可以将i
作为内部类的字段
Stream<String> stream = Stream.generate(new Supplier<String>() {
int i = 0;
// if you have any other state you want to mutate, put it here as well!
@Override
public String get() {
return "Hello" + i++;
}
});
// prints Hello0 to Hello9!
System.out.println(stream.limit(10).collect(Collectors.toList()));
Stream=Stream.generate(新供应商(){
int i=0;
//如果你有任何其他状态你想变异,把它也放在这里!
@凌驾
公共字符串get(){
返回“Hello”+i++;
}
});
//将他从0打印到9!
System.out.println(stream.limit(10.collect)(collector.toList());
要使用阻塞队列
为流提供数据
,您需要生产者和消费者在不同的线程上运行
在这里,我使用我的主线程来使用流,并使用一个新线程通过阻塞队列
来演示
public void test(String[] args) {
// My queue
BlockingQueue<BigInteger> queue = new ArrayBlockingQueue<>(10);
// A Stream of it's contents.
Stream<BigInteger> biStream = Stream.generate(() -> {
try {
return queue.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
// Feed the queue from a thread.
new Thread(new Runnable() {
// Must be final to be accessible inside `run`.
final AtomicInteger i = new AtomicInteger();
@Override
public void run() {
// Slow feed to the queue.
while (true) {
// Add a new number to the queue.
queue.add(BigInteger.valueOf(i.getAndIncrement()));
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// DEMO - Consumes the queue printing contents as they arrive.
biStream.filter(x -> x.testBit(2))
.limit(20)
.forEach(x -> System.out.println(x));
}
公共无效测试(字符串[]args){
//我的队列
BlockingQueue=new ArrayBlockingQueue(10);
//一系列的内容。
Stream biStream=Stream.generate(()->{
试一试{
返回队列。take();
}捕捉(中断异常e){
抛出新的运行时异常(e);
}
});
//从线程馈送队列。
新线程(newrunnable()){
//必须是最终版本,才能在“运行”中访问。
最终AtomicInteger i=新的AtomicInteger();
@凌驾
公开募捐{
//向队列缓慢馈送。
while(true){
//向队列中添加新编号。
add(biginger.valueOf(i.getAndIncrement());
试一试{
睡眠(200);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}).start();
//演示-在打印内容到达时使用队列打印内容。
双流过滤器(x->x.testBit(2))
.限额(20)
.forEach(x->System.out.println(x));
}
true BlockingQueue至少需要两个线程……我今晚会在家里尝试……谢谢:)我想我得到了我需要的。当没有新元素时,每秒醒来调用queue.poll(1,TimeUnit.SECONDS)
又有什么意义呢?为什么不首先简单地调用take()
?@Holger-很好。固定的!我试图安静地处理中断异常
。@abcdef12没有两个线程,无论实现如何,都无法完成您想要的任务。如果当前线程正在等待数据到达,它将如何使数据可用?@daniu I采用了不同的方法来解决它。我根本不使用流。我现在使用阻塞队列,信号量。我创建了一个池,其中信号量控制生产者和消费者,并根据负载需求将线程分配给消费者/生产者。就像一个平衡器。