Is it a bad practice to append operations to a Stream in different methods?
Suppose I have a method used by multiple classes in my application. This method takes a Stream
as a parameter and applies a terminal operation forEach
in order to write the data to a file, something like the following:
public File writeStreamToTempFile(Stream stream) {
stream.forEach(item -> {
//some code to write item to a file
}
}
There are multiple callers of this method, and in some of those methods I need to transform the data, let's say using map function, like the following:
public void exportAnimalsData() {
Stream<Animal> animalStream = //fetch data from a DB
animals.filter(a -> a.type.equals("dog"))
.map(a -> //Do something useful to transform the Dogs);
writeStreamToTempFile(animalStream);
}
Not all the callers of the writeStreamToTempFile
method need to perform additional operations on the stream.
So my question is:
Is it a bad practice to apply operations to a stream in different methods?
I read somewhere that Stream should never be the return type of a method (the caller does not know if that method already consumes the stream or not), does it also apply for parameters of a method?
Should I just apply all the operations needed in the same method or is it ok to append intermediate operations to the same stream in a different method?
java java-8 java-stream
add a comment |
Suppose I have a method used by multiple classes in my application. This method takes a Stream
as a parameter and applies a terminal operation forEach
in order to write the data to a file, something like the following:
public File writeStreamToTempFile(Stream stream) {
stream.forEach(item -> {
//some code to write item to a file
}
}
There are multiple callers of this method, and in some of those methods I need to transform the data, let's say using map function, like the following:
public void exportAnimalsData() {
Stream<Animal> animalStream = //fetch data from a DB
animals.filter(a -> a.type.equals("dog"))
.map(a -> //Do something useful to transform the Dogs);
writeStreamToTempFile(animalStream);
}
Not all the callers of the writeStreamToTempFile
method need to perform additional operations on the stream.
So my question is:
Is it a bad practice to apply operations to a stream in different methods?
I read somewhere that Stream should never be the return type of a method (the caller does not know if that method already consumes the stream or not), does it also apply for parameters of a method?
Should I just apply all the operations needed in the same method or is it ok to append intermediate operations to the same stream in a different method?
java java-8 java-stream
3
Stream should never be the return type of a method sounds like a bad policy, one frequently violated by the JDK. It should be obvious that a method returning a stream wouldn't have consumed it.
– shmosel
Nov 21 '18 at 21:05
1
Look for “Methods … that return Stream” in docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
– Holger
Nov 22 '18 at 9:38
add a comment |
Suppose I have a method used by multiple classes in my application. This method takes a Stream
as a parameter and applies a terminal operation forEach
in order to write the data to a file, something like the following:
public File writeStreamToTempFile(Stream stream) {
stream.forEach(item -> {
//some code to write item to a file
}
}
There are multiple callers of this method, and in some of those methods I need to transform the data, let's say using map function, like the following:
public void exportAnimalsData() {
Stream<Animal> animalStream = //fetch data from a DB
animals.filter(a -> a.type.equals("dog"))
.map(a -> //Do something useful to transform the Dogs);
writeStreamToTempFile(animalStream);
}
Not all the callers of the writeStreamToTempFile
method need to perform additional operations on the stream.
So my question is:
Is it a bad practice to apply operations to a stream in different methods?
I read somewhere that Stream should never be the return type of a method (the caller does not know if that method already consumes the stream or not), does it also apply for parameters of a method?
Should I just apply all the operations needed in the same method or is it ok to append intermediate operations to the same stream in a different method?
java java-8 java-stream
Suppose I have a method used by multiple classes in my application. This method takes a Stream
as a parameter and applies a terminal operation forEach
in order to write the data to a file, something like the following:
public File writeStreamToTempFile(Stream stream) {
stream.forEach(item -> {
//some code to write item to a file
}
}
There are multiple callers of this method, and in some of those methods I need to transform the data, let's say using map function, like the following:
public void exportAnimalsData() {
Stream<Animal> animalStream = //fetch data from a DB
animals.filter(a -> a.type.equals("dog"))
.map(a -> //Do something useful to transform the Dogs);
writeStreamToTempFile(animalStream);
}
Not all the callers of the writeStreamToTempFile
method need to perform additional operations on the stream.
So my question is:
Is it a bad practice to apply operations to a stream in different methods?
I read somewhere that Stream should never be the return type of a method (the caller does not know if that method already consumes the stream or not), does it also apply for parameters of a method?
Should I just apply all the operations needed in the same method or is it ok to append intermediate operations to the same stream in a different method?
java java-8 java-stream
java java-8 java-stream
edited Nov 21 '18 at 22:32


john
1,50451927
1,50451927
asked Nov 21 '18 at 20:18
Luis MiguelLuis Miguel
91110
91110
3
Stream should never be the return type of a method sounds like a bad policy, one frequently violated by the JDK. It should be obvious that a method returning a stream wouldn't have consumed it.
– shmosel
Nov 21 '18 at 21:05
1
Look for “Methods … that return Stream” in docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
– Holger
Nov 22 '18 at 9:38
add a comment |
3
Stream should never be the return type of a method sounds like a bad policy, one frequently violated by the JDK. It should be obvious that a method returning a stream wouldn't have consumed it.
– shmosel
Nov 21 '18 at 21:05
1
Look for “Methods … that return Stream” in docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
– Holger
Nov 22 '18 at 9:38
3
3
Stream should never be the return type of a method sounds like a bad policy, one frequently violated by the JDK. It should be obvious that a method returning a stream wouldn't have consumed it.
– shmosel
Nov 21 '18 at 21:05
Stream should never be the return type of a method sounds like a bad policy, one frequently violated by the JDK. It should be obvious that a method returning a stream wouldn't have consumed it.
– shmosel
Nov 21 '18 at 21:05
1
1
Look for “Methods … that return Stream” in docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
– Holger
Nov 22 '18 at 9:38
Look for “Methods … that return Stream” in docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
– Holger
Nov 22 '18 at 9:38
add a comment |
2 Answers
2
active
oldest
votes
i read somewhere that Stream should never be the return type of a method
Not sure where you read that a Stream
should never be the return type of a method. (Can you update your question with a link?).
On the contrary, Brian Goetz, one of the designers of the Stream API, clearly thinks otherwise:
https://stackoverflow.com/a/24679745/340088
(the caller does not know if that method already consume the stream or not)
If the caller is getting a Stream
it is implicitly understood that the stream is usable. If you return a consumed Stream
it is like returning a closed Socket
or a closed InputStream
. While possible syntactically, it is just bad coding. Doesn't mean you shouldn't return a Socket
or an InputStream
from a method just because some bad coder occasionally returns one in a bad state.
On the contrary, monadic style objects are intended to be returned. Stream
, Optional
, CompletableFuture
, and all the functional interfaces (Function
, Consumer
, Operator
, etc.) are intended to be returned so that more functional-style operations can be attached to them, without actually performing the function on the spot.
The example you posted, to me, is perfectly reasonable. You are sort of decorating your Stream
with additional operations to the pipeline. You can have logic which decides which operations are added to the pipeline, and there is no reason why not to encapsulate them properly in small methods.
Furthermore, if the stream is very large carrying hundreds of thousands of elements, if you returned a collection, you would just be creating a huge collection in memory, incurring the cost to add them all, only to then stream them again to write them to the file. Doesn't make much sense does it?
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
3
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to returnStream
(or any other functional type for that matter). Just do your code readable and sensibly organised.
– jbx
Nov 21 '18 at 21:18
add a comment |
should i just apply all the operations needed in the same method or is
it ok to append intermediate operations to the same stream in
different method?
Technically it is not necessarily the same stream/object. For example invoking an operation such as map()
on the stream will create another stream.
In fact I think that while you didn't consume the stream with a terminal operation I don't see why it would be an issue to work on it to create or get the expected stream and then to pass to the method that expects a Stream.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419885%2fis-it-a-bad-practice-to-append-operations-to-a-stream-in-different-methods%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
i read somewhere that Stream should never be the return type of a method
Not sure where you read that a Stream
should never be the return type of a method. (Can you update your question with a link?).
On the contrary, Brian Goetz, one of the designers of the Stream API, clearly thinks otherwise:
https://stackoverflow.com/a/24679745/340088
(the caller does not know if that method already consume the stream or not)
If the caller is getting a Stream
it is implicitly understood that the stream is usable. If you return a consumed Stream
it is like returning a closed Socket
or a closed InputStream
. While possible syntactically, it is just bad coding. Doesn't mean you shouldn't return a Socket
or an InputStream
from a method just because some bad coder occasionally returns one in a bad state.
On the contrary, monadic style objects are intended to be returned. Stream
, Optional
, CompletableFuture
, and all the functional interfaces (Function
, Consumer
, Operator
, etc.) are intended to be returned so that more functional-style operations can be attached to them, without actually performing the function on the spot.
The example you posted, to me, is perfectly reasonable. You are sort of decorating your Stream
with additional operations to the pipeline. You can have logic which decides which operations are added to the pipeline, and there is no reason why not to encapsulate them properly in small methods.
Furthermore, if the stream is very large carrying hundreds of thousands of elements, if you returned a collection, you would just be creating a huge collection in memory, incurring the cost to add them all, only to then stream them again to write them to the file. Doesn't make much sense does it?
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
3
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to returnStream
(or any other functional type for that matter). Just do your code readable and sensibly organised.
– jbx
Nov 21 '18 at 21:18
add a comment |
i read somewhere that Stream should never be the return type of a method
Not sure where you read that a Stream
should never be the return type of a method. (Can you update your question with a link?).
On the contrary, Brian Goetz, one of the designers of the Stream API, clearly thinks otherwise:
https://stackoverflow.com/a/24679745/340088
(the caller does not know if that method already consume the stream or not)
If the caller is getting a Stream
it is implicitly understood that the stream is usable. If you return a consumed Stream
it is like returning a closed Socket
or a closed InputStream
. While possible syntactically, it is just bad coding. Doesn't mean you shouldn't return a Socket
or an InputStream
from a method just because some bad coder occasionally returns one in a bad state.
On the contrary, monadic style objects are intended to be returned. Stream
, Optional
, CompletableFuture
, and all the functional interfaces (Function
, Consumer
, Operator
, etc.) are intended to be returned so that more functional-style operations can be attached to them, without actually performing the function on the spot.
The example you posted, to me, is perfectly reasonable. You are sort of decorating your Stream
with additional operations to the pipeline. You can have logic which decides which operations are added to the pipeline, and there is no reason why not to encapsulate them properly in small methods.
Furthermore, if the stream is very large carrying hundreds of thousands of elements, if you returned a collection, you would just be creating a huge collection in memory, incurring the cost to add them all, only to then stream them again to write them to the file. Doesn't make much sense does it?
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
3
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to returnStream
(or any other functional type for that matter). Just do your code readable and sensibly organised.
– jbx
Nov 21 '18 at 21:18
add a comment |
i read somewhere that Stream should never be the return type of a method
Not sure where you read that a Stream
should never be the return type of a method. (Can you update your question with a link?).
On the contrary, Brian Goetz, one of the designers of the Stream API, clearly thinks otherwise:
https://stackoverflow.com/a/24679745/340088
(the caller does not know if that method already consume the stream or not)
If the caller is getting a Stream
it is implicitly understood that the stream is usable. If you return a consumed Stream
it is like returning a closed Socket
or a closed InputStream
. While possible syntactically, it is just bad coding. Doesn't mean you shouldn't return a Socket
or an InputStream
from a method just because some bad coder occasionally returns one in a bad state.
On the contrary, monadic style objects are intended to be returned. Stream
, Optional
, CompletableFuture
, and all the functional interfaces (Function
, Consumer
, Operator
, etc.) are intended to be returned so that more functional-style operations can be attached to them, without actually performing the function on the spot.
The example you posted, to me, is perfectly reasonable. You are sort of decorating your Stream
with additional operations to the pipeline. You can have logic which decides which operations are added to the pipeline, and there is no reason why not to encapsulate them properly in small methods.
Furthermore, if the stream is very large carrying hundreds of thousands of elements, if you returned a collection, you would just be creating a huge collection in memory, incurring the cost to add them all, only to then stream them again to write them to the file. Doesn't make much sense does it?
i read somewhere that Stream should never be the return type of a method
Not sure where you read that a Stream
should never be the return type of a method. (Can you update your question with a link?).
On the contrary, Brian Goetz, one of the designers of the Stream API, clearly thinks otherwise:
https://stackoverflow.com/a/24679745/340088
(the caller does not know if that method already consume the stream or not)
If the caller is getting a Stream
it is implicitly understood that the stream is usable. If you return a consumed Stream
it is like returning a closed Socket
or a closed InputStream
. While possible syntactically, it is just bad coding. Doesn't mean you shouldn't return a Socket
or an InputStream
from a method just because some bad coder occasionally returns one in a bad state.
On the contrary, monadic style objects are intended to be returned. Stream
, Optional
, CompletableFuture
, and all the functional interfaces (Function
, Consumer
, Operator
, etc.) are intended to be returned so that more functional-style operations can be attached to them, without actually performing the function on the spot.
The example you posted, to me, is perfectly reasonable. You are sort of decorating your Stream
with additional operations to the pipeline. You can have logic which decides which operations are added to the pipeline, and there is no reason why not to encapsulate them properly in small methods.
Furthermore, if the stream is very large carrying hundreds of thousands of elements, if you returned a collection, you would just be creating a huge collection in memory, incurring the cost to add them all, only to then stream them again to write them to the file. Doesn't make much sense does it?
edited Nov 21 '18 at 21:08
answered Nov 21 '18 at 20:30
jbxjbx
11.4k1060111
11.4k1060111
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
3
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to returnStream
(or any other functional type for that matter). Just do your code readable and sensibly organised.
– jbx
Nov 21 '18 at 21:18
add a comment |
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
3
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to returnStream
(or any other functional type for that matter). Just do your code readable and sensibly organised.
– jbx
Nov 21 '18 at 21:18
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
Trying to find the video where i heard that it is not recommended to return a Stream from a method, will update the question once i find it. BTW great answer, thanks.
– Luis Miguel
Nov 21 '18 at 21:12
3
3
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to return
Stream
(or any other functional type for that matter). Just do your code readable and sensibly organised.– jbx
Nov 21 '18 at 21:18
Would be interested to see it. But its probably wrong (or contextually different). Rest assured its perfectly fine to return
Stream
(or any other functional type for that matter). Just do your code readable and sensibly organised.– jbx
Nov 21 '18 at 21:18
add a comment |
should i just apply all the operations needed in the same method or is
it ok to append intermediate operations to the same stream in
different method?
Technically it is not necessarily the same stream/object. For example invoking an operation such as map()
on the stream will create another stream.
In fact I think that while you didn't consume the stream with a terminal operation I don't see why it would be an issue to work on it to create or get the expected stream and then to pass to the method that expects a Stream.
add a comment |
should i just apply all the operations needed in the same method or is
it ok to append intermediate operations to the same stream in
different method?
Technically it is not necessarily the same stream/object. For example invoking an operation such as map()
on the stream will create another stream.
In fact I think that while you didn't consume the stream with a terminal operation I don't see why it would be an issue to work on it to create or get the expected stream and then to pass to the method that expects a Stream.
add a comment |
should i just apply all the operations needed in the same method or is
it ok to append intermediate operations to the same stream in
different method?
Technically it is not necessarily the same stream/object. For example invoking an operation such as map()
on the stream will create another stream.
In fact I think that while you didn't consume the stream with a terminal operation I don't see why it would be an issue to work on it to create or get the expected stream and then to pass to the method that expects a Stream.
should i just apply all the operations needed in the same method or is
it ok to append intermediate operations to the same stream in
different method?
Technically it is not necessarily the same stream/object. For example invoking an operation such as map()
on the stream will create another stream.
In fact I think that while you didn't consume the stream with a terminal operation I don't see why it would be an issue to work on it to create or get the expected stream and then to pass to the method that expects a Stream.
answered Nov 21 '18 at 20:28


davidxxxdavidxxx
66.5k66995
66.5k66995
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419885%2fis-it-a-bad-practice-to-append-operations-to-a-stream-in-different-methods%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Stream should never be the return type of a method sounds like a bad policy, one frequently violated by the JDK. It should be obvious that a method returning a stream wouldn't have consumed it.
– shmosel
Nov 21 '18 at 21:05
1
Look for “Methods … that return Stream” in docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
– Holger
Nov 22 '18 at 9:38