-1

I want to transfer data generated by a method in a class to another method in another class. I assume this can be done with Streams but I am not sure if this is the right way. Below is the pseudo code of what I am trying to achieve:

Class1.java

static Stream stream1; 
getDataFromUpstream(List<SomeData> data){
    Stream2 = Stream.of(data);
    stream1.concat(stream2);
}

Class2.java

getData() {
    Class1.stream1.forEach(data -> //do something);
}

If this can be achieved using streams, kindly suggest how. Otherwise, if there is any other way of streaming data like this in Java, please let me know.

I cannot call getData() method from getDataFromUpstream() directly.

Piyush Shrivastava
  • 1,046
  • 2
  • 16
  • 43
  • 2
    When you try to transform this into valid Java code, you’ll notice that methods have *return types*. Which is the preferred way to hand data over to a caller, rather than static variables. To pass data into the other direction, use parameters. Besides that, Streams are not Collections. There is no `append` method. Instead, you can create a Stream from a Collection, but this is not necessary here. – Holger Jun 07 '23 at 11:24
  • When you get around to consulting the Javadoc you will find that `Stream` doesn't have an `append()` method. Or you could just keep guessing. – user207421 Jun 07 '23 at 11:36
  • Updated the question. That was just a pseudo code. – Piyush Shrivastava Jun 07 '23 at 12:13
  • Do you need to use Streams at all? What is the upstream that needs to be gotten. You should not keep a reference to a stream as your data because they can be consumed. ie `Class1.stream1.forEach()` is a terminal operation. Then stream1 will have been consumed. Why not just keep a List? – matt Jun 07 '23 at 12:40
  • @matt I need to keep appending data and reading. Like a data stream. – Piyush Shrivastava Jun 07 '23 at 12:42

2 Answers2

1

If you want to create an infinite stream of sorts where you keep providing data and elements can continue reading from it. You can use Stream#generate.

KindaInfinite<T>{
    LinkedBlockingQueue<T>  queue = new LinkedBlockingQueue();
    Stream<T> getInfiniteStream(){
        return Stream.generate( () -> {
            try{
                return queue.take();
            catch(Exception e){
                throw new RuntimeException(e);
            }
        });
    }
    public void addData(List<T> data){
        queue.addAll(data);
    }
}

Now you can run,

KindaInfinite<String> strings = new KindaInfinite<>();
Stream<String> stream = strings.getInfiniteStream();
stream.forEach( s-> System.out.println(s));

The forEach will never return because it will always be trying to consume the new elements. You would need a second thread to add items to the KindaInfinite to consume them.

You could limit the stream by using takeWhile and sending a special value, as per this anser.

I would probably just use the Queue without the stream though.

matt
  • 10,892
  • 3
  • 22
  • 34
0

You can't append collection or more elements to a stream. You can however concatenate 2 streams together using Stream.concat(), by getting another stream from your collection.

static void getDataFromUpstream(List<SomeData> data){
  stream1 = Stream.concat(stream1, data.stream());
}

Edit: Since you want to keep appending and reading, a Queue would be more appropriate.

static Queue<SomeData> queue;

static void getDataFromUpstream(List<SomeData> data){
  queue.addAll(data);
}

You can't achieve this with a stream, because you can't add elements to it.

Chaosfire
  • 4,818
  • 4
  • 8
  • 23
  • Updated the question. That was just a pseudo code. – Piyush Shrivastava Jun 07 '23 at 12:13
  • @PiyushShrivastava Your updated pseudo code won't work, you can't use `concat()` on a stream instance, it's a static method. The code in this answer shows exactly how you need to use `Stream.concat()`. – Chaosfire Jun 07 '23 at 12:23
  • This is not about how to use Stream.concat(). I want to transfer data from one class to other using streams. – Piyush Shrivastava Jun 07 '23 at 12:41
  • @PiyushShrivastava You can't do that with a stream, it's **not** a collection, it's not used to transfer data. It is - `A sequence of elements supporting sequential and parallel aggregate operations.`, so the API does not allow you to add elements. Judging by your comment on the question, you need to use a [Queue](https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html). – Chaosfire Jun 07 '23 at 12:52