How do I get the first element while continue streaming?2019 Community Moderator ElectionCan I duplicate a...
How to draw tikz paths composed only of horizontal, vertical and diagonal segments?
How do you make a gun that throws swords?
Should I use HTTPS on a domain that will only be used for redirection?
The need of reserving one's ability in job interviews
How can friction do no work in case of pure rolling?
Is there a math equivalent to the conditional ternary operator?
Number of folds to form a cube, using a square paper?
How to chmod files that have a specific set of permissions
How does insurance birth control work?
Why would the IRS ask for birth certificates or even audit a small tax return?
What is brightness?
The (Easy) Road to Code
How to concatenate two command in shell
Can a Tiny Servant be used as a messenger?
Are Wave equations equivalent to Maxwell equations?
Searching for a string that contains the file name
How do I deal with being envious of my own players?
Practical reasons to have both a large police force and bounty hunting network?
Specific Chinese carabiner QA?
ToC header appears in next chapter
How can I handle a player who pre-plans arguments about my rulings on RAW?
Where is this quote about overcoming the impossible said in "Interstellar"?
Are there other characters in the Star Wars universe who had damaged bodies and needed to wear an outfit like Darth Vader?
What is a term for a function that when called repeatedly, has the same effect as calling once?
How do I get the first element while continue streaming?
2019 Community Moderator ElectionCan I duplicate a Stream in Java 8?How to iterate with foreach loop over java 8 streamHow to match stream elements but return false if non exists?Performing specific operation on first element of list using Java8 streamingHow to get an enum value from a string value in Java?Efficiency of Java “Double Brace Initialization”?Java Security: Illegal key size or default parameters?Ways to iterate over a list in JavaHow to Convert a Java 8 Stream to an Array?Find first element by predicateRemove and collect elements with Java streamsStream Way to get index of first element matching booleanStream of cartesian product of other streams, each element as a List?Java Stream groupingBy where key is an element in a sublist
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);
}
Can I do this on a stream (Stream<T>
) with the stream API?
* 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);
}
Can I do this on a stream (Stream<T>
) with the stream API?
* 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
21 hours ago
@AndrewTobilko - I don't have anIterable
- justStream
.
– AlikElzin-kilaka
18 hours ago
Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).
– Ilmari Karonen
5 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);
}
Can I do this on a stream (Stream<T>
) with the stream API?
* 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);
}
Can I do this on a stream (Stream<T>
) with the stream API?
* 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 4 hours ago
Peter Mortensen
13.7k1986113
13.7k1986113
asked 21 hours ago
AlikElzin-kilakaAlikElzin-kilaka
18.7k15126203
18.7k15126203
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
21 hours ago
@AndrewTobilko - I don't have anIterable
- justStream
.
– AlikElzin-kilaka
18 hours ago
Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).
– Ilmari Karonen
5 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
21 hours ago
@AndrewTobilko - I don't have anIterable
- justStream
.
– AlikElzin-kilaka
18 hours ago
Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).
– Ilmari Karonen
5 hours ago
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
21 hours ago
Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.
– AlikElzin-kilaka
21 hours ago
@AndrewTobilko - I don't have an
Iterable
- just Stream
.– AlikElzin-kilaka
18 hours ago
@AndrewTobilko - I don't have an
Iterable
- just Stream
.– AlikElzin-kilaka
18 hours ago
Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).
– Ilmari Karonen
5 hours ago
Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).
– Ilmari Karonen
5 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
21 hours ago
1
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 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
20 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
20 hours ago
add a comment |
Native solution: 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
21 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
21 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
21 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
20 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 |
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
.
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 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
21 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
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 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
20 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 |
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-do-i-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
21 hours ago
1
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 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
20 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
20 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
21 hours ago
1
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 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
20 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
20 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 21 hours ago
Andrew Tobilko
28k104388
28k104388
answered 21 hours ago
RuslanRuslan
3,050823
3,050823
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
21 hours ago
1
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 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
20 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
20 hours ago
add a comment |
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
21 hours ago
1
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 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
20 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
20 hours ago
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
21 hours ago
I wonder how they've implemented it, probably like one of the solutions already given here
– Lino
21 hours ago
1
1
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 hours ago
note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".
– Andrew Tobilko
21 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
20 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
20 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
20 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
20 hours ago
add a comment |
Native solution: 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
21 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
21 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
21 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
20 hours ago
add a comment |
Native solution: 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
21 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
21 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
21 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
20 hours ago
add a comment |
Native solution: 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.
Native solution: 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 21 hours ago
AndronicusAndronicus
3,52921429
3,52921429
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
21 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
21 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
21 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
20 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
21 hours ago
Why do you assume that it's safe to cast:(List<E>) itemIter
?
– ernest_k
21 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
21 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
20 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
21 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
21 hours ago
Why do you assume that it's safe to cast:
(List<E>) itemIter
?– ernest_k
21 hours ago
Why do you assume that it's safe to cast:
(List<E>) itemIter
?– ernest_k
21 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
21 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
21 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
20 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
20 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 21 hours ago
answered 21 hours ago
Benjamin UrquhartBenjamin Urquhart
905
905
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
.
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 hours ago
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
.
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 hours ago
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 19 hours ago
HolgerHolger
168k23238453
168k23238453
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 hours ago
add a comment |
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 hours ago
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
can't tell why this is not a lot higher :|
– Eugene
5 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 hours ago
@Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about
– Holger
3 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
21 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
21 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 21 hours ago
Mohammad AdilMohammad Adil
39.5k1471100
39.5k1471100
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
21 hours ago
add a comment |
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
21 hours ago
1
1
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
21 hours ago
requires you to always reset the value though, and will not work in a multi thread environment
– Lino
21 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
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 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
20 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
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 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
20 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 21 hours ago
answered 21 hours ago
LinoLino
9,76822043
9,76822043
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
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 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
20 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
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 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
20 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
21 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
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 hours ago
@nullpointer you're right, I've edited my answer to use StreamSupport
– Lino
21 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
20 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
20 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 21 hours ago
ernest_kernest_k
23.4k42649
23.4k42649
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-do-i-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
21 hours ago
@AndrewTobilko - I don't have an
Iterable
- justStream
.– AlikElzin-kilaka
18 hours ago
Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).
– Ilmari Karonen
5 hours ago