How to get the first element while continue streaming?
I have a stream of generic items. I'd like to print the class name of the first item + the toString()
of all the items.
If I had an Iterable, it would look like this:
Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}
Any idea if I can do this on a stream (Stream<T>
) with stream api? Thanks.
* Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
java java-stream
add a comment |
I have a stream of generic items. I'd like to print the class name of the first item + the toString()
of all the items.
If I had an Iterable, it would look like this:
Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}
Any idea if I can do this on a stream (Stream<T>
) with stream api? Thanks.
* Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
java java-stream
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
10 hours ago
@AndrewTobilko - I don't have anIterable
- justStream
.
– AlikElzin-kilaka
7 hours ago
add a comment |
I have a stream of generic items. I'd like to print the class name of the first item + the toString()
of all the items.
If I had an Iterable, it would look like this:
Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}
Any idea if I can do this on a stream (Stream<T>
) with stream api? Thanks.
* Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
java java-stream
I have a stream of generic items. I'd like to print the class name of the first item + the toString()
of all the items.
If I had an Iterable, it would look like this:
Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}
Any idea if I can do this on a stream (Stream<T>
) with stream api? Thanks.
* Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
java java-stream
java java-stream
edited 5 hours ago
Rakete1111
35k1083119
35k1083119
asked 10 hours ago
AlikElzin-kilakaAlikElzin-kilaka
18.7k15126202
18.7k15126202
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
10 hours ago
@AndrewTobilko - I don't have anIterable
- justStream
.
– AlikElzin-kilaka
7 hours ago
add a comment |
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
10 hours ago
@AndrewTobilko - I don't have anIterable
- justStream
.
– AlikElzin-kilaka
7 hours ago
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
10 hours ago
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
10 hours ago
@AndrewTobilko - I don't have an
Iterable
- just Stream
.– AlikElzin-kilaka
7 hours ago
@AndrewTobilko - I don't have an
Iterable
- just Stream
.– AlikElzin-kilaka
7 hours ago
add a comment |
7 Answers
7
active
oldest
votes
There is StreamEx
library that extends standard Java's Stream API. Using StreamEx.of(Iterator)
and peekFirst
:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
1
By the way, it’s preferable to useStreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actualIterable
), potentially improving the performance.
– Holger
8 hours ago
add a comment |
Stream
in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.
Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
Edit
There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.
1
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (whatitemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)
– Andronicus
9 hours ago
1
Well, it doesn’t even compile. Since objects are not anIterable
and anIterator
at the same time, you can’t cast it toList
and expect it to also have anext()
method. Once you fixed this, you don’t need the questionable type cast:E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
add a comment |
You can abuse reduction:
Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
+ e));
add a comment |
One workaround is to do it like this -
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
static int i = 0;
static int getCounter(){
return i;
}
static void incrementCounter(){
i++;
}
public static void main(String args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
List<String> answer = list.stream().filter(str -> {if(getCounter()==0) {System.out.println("First Element : " + str);} incrementCounter(); return true;}).
collect(Collectors.toList());
System.out.println(answer);
}
}
Output :
First Element : A
[A, B, C, D, E, F, G]
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
add a comment |
You could use peek
for that:
AtomicBoolean first = new AtomicBoolean(true);
StreamSupport.stream(itemIter.spliterator(), false)
.peek(e -> {
if(first.get()) {
System.out.println(e.getClass().getSimpleName());
first.set(false);
}
})
...
1
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing likeitemIter.stream()
available up front.
– nullpointer
10 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
The action passed topeek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.
– Holger
8 hours ago
add a comment |
You can also use an boolean atomic reference:
AtomicReference<Boolean> first = new AtomicReference<Boolean>(Boolean.TRUE);
stream.forEach(e ->
System.out.println("First == " + first.getAndUpdate(b -> false)));
add a comment |
If your starting point is a Stream
and you want to retain all of its properties and the laziness, the following solution will do:
public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
boolean parallel = stream.isParallel();
Spliterator<E> sp = stream.spliterator();
return StreamSupport.stream(() -> {
if(sp.getExactSizeIfKnown() == 0) return sp;
Stream.Builder<E> b = Stream.builder();
if(!sp.tryAdvance(b.andThen(c))) return sp;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
}, sp.characteristics(), parallel);
}
E.g. when you use it with
List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
Stream<String> stream = forFirst(
list.stream().filter(s -> s.startsWith("b")),
s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
).map(String::toUpperCase);
list.add(1, "blah");
System.out.println(stream.collect(Collectors.joining(" | ")));
it will print
blah (String)
BLAH | BAR | BAZ
demonstrating that the processing will not start before commencing the terminal operation (collect
), hence reflecting the preceding update to the source List
.
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%2f55027574%2fhow-to-get-the-first-element-while-continue-streaming%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
There is StreamEx
library that extends standard Java's Stream API. Using StreamEx.of(Iterator)
and peekFirst
:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
1
By the way, it’s preferable to useStreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actualIterable
), potentially improving the performance.
– Holger
8 hours ago
add a comment |
There is StreamEx
library that extends standard Java's Stream API. Using StreamEx.of(Iterator)
and peekFirst
:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
1
By the way, it’s preferable to useStreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actualIterable
), potentially improving the performance.
– Holger
8 hours ago
add a comment |
There is StreamEx
library that extends standard Java's Stream API. Using StreamEx.of(Iterator)
and peekFirst
:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
There is StreamEx
library that extends standard Java's Stream API. Using StreamEx.of(Iterator)
and peekFirst
:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
edited 9 hours ago
Andrew Tobilko
27.9k104388
27.9k104388
answered 10 hours ago
RuslanRuslan
3,030822
3,030822
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
1
By the way, it’s preferable to useStreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actualIterable
), potentially improving the performance.
– Holger
8 hours ago
add a comment |
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
1
By the way, it’s preferable to useStreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actualIterable
), potentially improving the performance.
– Holger
8 hours ago
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
@Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.
– Holger
9 hours ago
1
1
By the way, it’s preferable to use
StreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actual Iterable
), potentially improving the performance.– Holger
8 hours ago
By the way, it’s preferable to use
StreamEx.of(itemIter.spliterator())
, which may carry additional meta information to the stream (depending on the actual Iterable
), potentially improving the performance.– Holger
8 hours ago
add a comment |
Stream
in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.
Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
Edit
There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.
1
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (whatitemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)
– Andronicus
9 hours ago
1
Well, it doesn’t even compile. Since objects are not anIterable
and anIterator
at the same time, you can’t cast it toList
and expect it to also have anext()
method. Once you fixed this, you don’t need the questionable type cast:E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
add a comment |
Stream
in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.
Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
Edit
There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.
1
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (whatitemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)
– Andronicus
9 hours ago
1
Well, it doesn’t even compile. Since objects are not anIterable
and anIterator
at the same time, you can’t cast it toList
and expect it to also have anext()
method. Once you fixed this, you don’t need the questionable type cast:E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
add a comment |
Stream
in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.
Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
Edit
There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.
Stream
in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.
Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
Edit
There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.
edited 8 hours ago
answered 10 hours ago
AndronicusAndronicus
3,45921429
3,45921429
1
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (whatitemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)
– Andronicus
9 hours ago
1
Well, it doesn’t even compile. Since objects are not anIterable
and anIterator
at the same time, you can’t cast it toList
and expect it to also have anext()
method. Once you fixed this, you don’t need the questionable type cast:E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
add a comment |
1
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (whatitemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)
– Andronicus
9 hours ago
1
Well, it doesn’t even compile. Since objects are not anIterable
and anIterator
at the same time, you can’t cast it toList
and expect it to also have anext()
method. Once you fixed this, you don’t need the questionable type cast:E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
1
1
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
@AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.
– Andrew Tobilko
9 hours ago
Why do you assume that it's safe to cast:
(List<E>) itemIter
?– ernest_k
9 hours ago
Why do you assume that it's safe to cast:
(List<E>) itemIter
?– ernest_k
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (what
itemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)– Andronicus
9 hours ago
@ernest_k it doesn't really matter, I don't know the context (what
itemIter
really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)– Andronicus
9 hours ago
1
1
Well, it doesn’t even compile. Since objects are not an
Iterable
and an Iterator
at the same time, you can’t cast it to List
and expect it to also have a next()
method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
Well, it doesn’t even compile. Since objects are not an
Iterable
and an Iterator
at the same time, you can’t cast it to List
and expect it to also have a next()
method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);
– Holger
8 hours ago
add a comment |
You can abuse reduction:
Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
+ e));
add a comment |
You can abuse reduction:
Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
+ e));
add a comment |
You can abuse reduction:
Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
+ e));
You can abuse reduction:
Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
+ e));
edited 9 hours ago
answered 10 hours ago
Benjamin UrquhartBenjamin Urquhart
905
905
add a comment |
add a comment |
One workaround is to do it like this -
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
static int i = 0;
static int getCounter(){
return i;
}
static void incrementCounter(){
i++;
}
public static void main(String args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
List<String> answer = list.stream().filter(str -> {if(getCounter()==0) {System.out.println("First Element : " + str);} incrementCounter(); return true;}).
collect(Collectors.toList());
System.out.println(answer);
}
}
Output :
First Element : A
[A, B, C, D, E, F, G]
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
add a comment |
One workaround is to do it like this -
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
static int i = 0;
static int getCounter(){
return i;
}
static void incrementCounter(){
i++;
}
public static void main(String args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
List<String> answer = list.stream().filter(str -> {if(getCounter()==0) {System.out.println("First Element : " + str);} incrementCounter(); return true;}).
collect(Collectors.toList());
System.out.println(answer);
}
}
Output :
First Element : A
[A, B, C, D, E, F, G]
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
add a comment |
One workaround is to do it like this -
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
static int i = 0;
static int getCounter(){
return i;
}
static void incrementCounter(){
i++;
}
public static void main(String args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
List<String> answer = list.stream().filter(str -> {if(getCounter()==0) {System.out.println("First Element : " + str);} incrementCounter(); return true;}).
collect(Collectors.toList());
System.out.println(answer);
}
}
Output :
First Element : A
[A, B, C, D, E, F, G]
One workaround is to do it like this -
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
static int i = 0;
static int getCounter(){
return i;
}
static void incrementCounter(){
i++;
}
public static void main(String args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
List<String> answer = list.stream().filter(str -> {if(getCounter()==0) {System.out.println("First Element : " + str);} incrementCounter(); return true;}).
collect(Collectors.toList());
System.out.println(answer);
}
}
Output :
First Element : A
[A, B, C, D, E, F, G]
answered 10 hours ago
Mohammad AdilMohammad Adil
39.4k1471100
39.4k1471100
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
add a comment |
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
1
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
9 hours ago
add a comment |
You could use peek
for that:
AtomicBoolean first = new AtomicBoolean(true);
StreamSupport.stream(itemIter.spliterator(), false)
.peek(e -> {
if(first.get()) {
System.out.println(e.getClass().getSimpleName());
first.set(false);
}
})
...
1
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing likeitemIter.stream()
available up front.
– nullpointer
10 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
The action passed topeek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.
– Holger
8 hours ago
add a comment |
You could use peek
for that:
AtomicBoolean first = new AtomicBoolean(true);
StreamSupport.stream(itemIter.spliterator(), false)
.peek(e -> {
if(first.get()) {
System.out.println(e.getClass().getSimpleName());
first.set(false);
}
})
...
1
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing likeitemIter.stream()
available up front.
– nullpointer
10 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
The action passed topeek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.
– Holger
8 hours ago
add a comment |
You could use peek
for that:
AtomicBoolean first = new AtomicBoolean(true);
StreamSupport.stream(itemIter.spliterator(), false)
.peek(e -> {
if(first.get()) {
System.out.println(e.getClass().getSimpleName());
first.set(false);
}
})
...
You could use peek
for that:
AtomicBoolean first = new AtomicBoolean(true);
StreamSupport.stream(itemIter.spliterator(), false)
.peek(e -> {
if(first.get()) {
System.out.println(e.getClass().getSimpleName());
first.set(false);
}
})
...
edited 9 hours ago
answered 10 hours ago
LinoLino
9,76922043
9,76922043
1
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing likeitemIter.stream()
available up front.
– nullpointer
10 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
The action passed topeek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.
– Holger
8 hours ago
add a comment |
1
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing likeitemIter.stream()
available up front.
– nullpointer
10 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
The action passed topeek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.
– Holger
8 hours ago
1
1
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing like
itemIter.stream()
available up front.– nullpointer
10 hours ago
In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing like
itemIter.stream()
available up front.– nullpointer
10 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
9 hours ago
The action passed to
peek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.– Holger
8 hours ago
The action passed to
peek
will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.– Holger
8 hours ago
add a comment |
You can also use an boolean atomic reference:
AtomicReference<Boolean> first = new AtomicReference<Boolean>(Boolean.TRUE);
stream.forEach(e ->
System.out.println("First == " + first.getAndUpdate(b -> false)));
add a comment |
You can also use an boolean atomic reference:
AtomicReference<Boolean> first = new AtomicReference<Boolean>(Boolean.TRUE);
stream.forEach(e ->
System.out.println("First == " + first.getAndUpdate(b -> false)));
add a comment |
You can also use an boolean atomic reference:
AtomicReference<Boolean> first = new AtomicReference<Boolean>(Boolean.TRUE);
stream.forEach(e ->
System.out.println("First == " + first.getAndUpdate(b -> false)));
You can also use an boolean atomic reference:
AtomicReference<Boolean> first = new AtomicReference<Boolean>(Boolean.TRUE);
stream.forEach(e ->
System.out.println("First == " + first.getAndUpdate(b -> false)));
answered 9 hours ago
ernest_kernest_k
23.4k42649
23.4k42649
add a comment |
add a comment |
If your starting point is a Stream
and you want to retain all of its properties and the laziness, the following solution will do:
public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
boolean parallel = stream.isParallel();
Spliterator<E> sp = stream.spliterator();
return StreamSupport.stream(() -> {
if(sp.getExactSizeIfKnown() == 0) return sp;
Stream.Builder<E> b = Stream.builder();
if(!sp.tryAdvance(b.andThen(c))) return sp;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
}, sp.characteristics(), parallel);
}
E.g. when you use it with
List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
Stream<String> stream = forFirst(
list.stream().filter(s -> s.startsWith("b")),
s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
).map(String::toUpperCase);
list.add(1, "blah");
System.out.println(stream.collect(Collectors.joining(" | ")));
it will print
blah (String)
BLAH | BAR | BAZ
demonstrating that the processing will not start before commencing the terminal operation (collect
), hence reflecting the preceding update to the source List
.
add a comment |
If your starting point is a Stream
and you want to retain all of its properties and the laziness, the following solution will do:
public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
boolean parallel = stream.isParallel();
Spliterator<E> sp = stream.spliterator();
return StreamSupport.stream(() -> {
if(sp.getExactSizeIfKnown() == 0) return sp;
Stream.Builder<E> b = Stream.builder();
if(!sp.tryAdvance(b.andThen(c))) return sp;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
}, sp.characteristics(), parallel);
}
E.g. when you use it with
List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
Stream<String> stream = forFirst(
list.stream().filter(s -> s.startsWith("b")),
s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
).map(String::toUpperCase);
list.add(1, "blah");
System.out.println(stream.collect(Collectors.joining(" | ")));
it will print
blah (String)
BLAH | BAR | BAZ
demonstrating that the processing will not start before commencing the terminal operation (collect
), hence reflecting the preceding update to the source List
.
add a comment |
If your starting point is a Stream
and you want to retain all of its properties and the laziness, the following solution will do:
public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
boolean parallel = stream.isParallel();
Spliterator<E> sp = stream.spliterator();
return StreamSupport.stream(() -> {
if(sp.getExactSizeIfKnown() == 0) return sp;
Stream.Builder<E> b = Stream.builder();
if(!sp.tryAdvance(b.andThen(c))) return sp;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
}, sp.characteristics(), parallel);
}
E.g. when you use it with
List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
Stream<String> stream = forFirst(
list.stream().filter(s -> s.startsWith("b")),
s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
).map(String::toUpperCase);
list.add(1, "blah");
System.out.println(stream.collect(Collectors.joining(" | ")));
it will print
blah (String)
BLAH | BAR | BAZ
demonstrating that the processing will not start before commencing the terminal operation (collect
), hence reflecting the preceding update to the source List
.
If your starting point is a Stream
and you want to retain all of its properties and the laziness, the following solution will do:
public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
boolean parallel = stream.isParallel();
Spliterator<E> sp = stream.spliterator();
return StreamSupport.stream(() -> {
if(sp.getExactSizeIfKnown() == 0) return sp;
Stream.Builder<E> b = Stream.builder();
if(!sp.tryAdvance(b.andThen(c))) return sp;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
}, sp.characteristics(), parallel);
}
E.g. when you use it with
List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
Stream<String> stream = forFirst(
list.stream().filter(s -> s.startsWith("b")),
s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
).map(String::toUpperCase);
list.add(1, "blah");
System.out.println(stream.collect(Collectors.joining(" | ")));
it will print
blah (String)
BLAH | BAR | BAZ
demonstrating that the processing will not start before commencing the terminal operation (collect
), hence reflecting the preceding update to the source List
.
answered 8 hours ago
HolgerHolger
168k23238453
168k23238453
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%2f55027574%2fhow-to-get-the-first-element-while-continue-streaming%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
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
10 hours ago
@AndrewTobilko - I don't have an
Iterable
- justStream
.– AlikElzin-kilaka
7 hours ago