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

What would be the most expensive material to an intergalactic society?

How is it possible to drive VGA displays at such high pixel clock frequencies?

Does an unused member variable take up memory?

Called into a meeting and told we are being made redundant (laid off) and "not to share outside". Can I tell my partner?

Movie: boy escapes the real world and goes to a fantasy world with big furry trolls

Will expression retain the same definition if particle is changed?

Can't make sense of a paragraph from Lovecraft

Why aren't there more Gauls like Obelix?

What does *dead* mean in *What do you mean, dead?*?

Is there a logarithm base for which the logarithm becomes an identity function?

How do I increase the number of TTY consoles?

School performs periodic password audits. Is my password compromised?

Is divide-by-zero a security vulnerability?

One circle's diameter is different from others within a series of circles

How do you make a gun that shoots melee weapons and/or swords?

Does the US political system, in principle, allow for a no-party system?

How do spaceships determine each other's mass in space?

Can the Witch Sight warlock invocation see through the Mirror Image spell?

"If + would" conditional in present perfect tense

Is there a way to make cleveref distinguish two environments with the same counter?

If sound is a longitudinal wave, why can we hear it if our ears aren't aligned with the propagation direction?

Why is it common in European airports not to display the gate for flights until around 45-90 minutes before departure, unlike other places?

ESPP--any reason not to go all in?

What can I do if someone tampers with my SSH public key?



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










16















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.










share|improve this question
























  • Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.

    – AlikElzin-kilaka
    Mar 6 at 16:38











  • @AndrewTobilko - I don't have an Iterable - just Stream.

    – AlikElzin-kilaka
    Mar 6 at 19:29











  • Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).

    – Ilmari Karonen
    2 days ago















16















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.










share|improve this question
























  • Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.

    – AlikElzin-kilaka
    Mar 6 at 16:38











  • @AndrewTobilko - I don't have an Iterable - just Stream.

    – AlikElzin-kilaka
    Mar 6 at 19:29











  • Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).

    – Ilmari Karonen
    2 days ago













16












16








16


5






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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago









Peter Mortensen

13.7k1986113




13.7k1986113










asked Mar 6 at 16:13









AlikElzin-kilakaAlikElzin-kilaka

18.7k15126204




18.7k15126204












  • Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.

    – AlikElzin-kilaka
    Mar 6 at 16:38











  • @AndrewTobilko - I don't have an Iterable - just Stream.

    – AlikElzin-kilaka
    Mar 6 at 19:29











  • Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).

    – Ilmari Karonen
    2 days ago

















  • Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.

    – AlikElzin-kilaka
    Mar 6 at 16:38











  • @AndrewTobilko - I don't have an Iterable - just Stream.

    – AlikElzin-kilaka
    Mar 6 at 19:29











  • Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).

    – Ilmari Karonen
    2 days ago
















Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.

– AlikElzin-kilaka
Mar 6 at 16:38





Please note that it's a question about streams - not about iterators. I have a stream - not an iterator.

– AlikElzin-kilaka
Mar 6 at 16:38













@AndrewTobilko - I don't have an Iterable - just Stream.

– AlikElzin-kilaka
Mar 6 at 19:29





@AndrewTobilko - I don't have an Iterable - just Stream.

– AlikElzin-kilaka
Mar 6 at 19:29













Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).

– Ilmari Karonen
2 days ago





Note that, if you have a stream, you can get an iterator (and, if you need one, also an iterable).

– Ilmari Karonen
2 days ago












7 Answers
7






active

oldest

votes


















10














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);





share|improve this answer

























  • I wonder how they've implemented it, probably like one of the solutions already given here

    – Lino
    Mar 6 at 16:50






  • 1





    note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

    – Andrew Tobilko
    Mar 6 at 16:55











  • @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
    Mar 6 at 17:36






  • 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
    Mar 6 at 17:48


















7














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.






share|improve this answer




















  • 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
    Mar 6 at 16:44












  • Why do you assume that it's safe to cast: (List<E>) itemIter?

    – ernest_k
    Mar 6 at 16:46











  • @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
    Mar 6 at 16:48






  • 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
    Mar 6 at 17:44


















5














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.






share|improve this answer























  • can't tell why this is not a lot higher :|

    – Eugene
    2 days 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
    2 days ago


















4














You can abuse reduction:



Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
+ e));





share|improve this answer
































    0














    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]





    share|improve this answer


















    • 1





      requires you to always reset the value though, and will not work in a multi thread environment

      – Lino
      Mar 6 at 16:52


















    0














    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);

    )
    ...





    share|improve this answer




















    • 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
      Mar 6 at 16:36












    • @nullpointer you're right, I've edited my answer to use StreamSupport

      – Lino
      Mar 6 at 16:46











    • The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

      – Holger
      Mar 6 at 17:45


















    0














    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)));





    share|improve this answer






















      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
      );



      );













      draft saved

      draft discarded


















      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









      10














      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);





      share|improve this answer

























      • I wonder how they've implemented it, probably like one of the solutions already given here

        – Lino
        Mar 6 at 16:50






      • 1





        note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

        – Andrew Tobilko
        Mar 6 at 16:55











      • @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
        Mar 6 at 17:36






      • 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
        Mar 6 at 17:48















      10














      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);





      share|improve this answer

























      • I wonder how they've implemented it, probably like one of the solutions already given here

        – Lino
        Mar 6 at 16:50






      • 1





        note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

        – Andrew Tobilko
        Mar 6 at 16:55











      • @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
        Mar 6 at 17:36






      • 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
        Mar 6 at 17:48













      10












      10








      10







      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);





      share|improve this answer















      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);






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 6 at 16:50









      Andrew Tobilko

      28k104388




      28k104388










      answered Mar 6 at 16:31









      RuslanRuslan

      3,196824




      3,196824












      • I wonder how they've implemented it, probably like one of the solutions already given here

        – Lino
        Mar 6 at 16:50






      • 1





        note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

        – Andrew Tobilko
        Mar 6 at 16:55











      • @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
        Mar 6 at 17:36






      • 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
        Mar 6 at 17:48

















      • I wonder how they've implemented it, probably like one of the solutions already given here

        – Lino
        Mar 6 at 16:50






      • 1





        note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

        – Andrew Tobilko
        Mar 6 at 16:55











      • @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
        Mar 6 at 17:36






      • 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
        Mar 6 at 17:48
















      I wonder how they've implemented it, probably like one of the solutions already given here

      – Lino
      Mar 6 at 16:50





      I wonder how they've implemented it, probably like one of the solutions already given here

      – Lino
      Mar 6 at 16:50




      1




      1





      note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

      – Andrew Tobilko
      Mar 6 at 16:55





      note that the method has some limitations (mentioned in the docs) and "exists mainly to support debugging".

      – Andrew Tobilko
      Mar 6 at 16:55













      @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
      Mar 6 at 17:36





      @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
      Mar 6 at 17:36




      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
      Mar 6 at 17:48





      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
      Mar 6 at 17:48













      7














      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.






      share|improve this answer




















      • 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
        Mar 6 at 16:44












      • Why do you assume that it's safe to cast: (List<E>) itemIter?

        – ernest_k
        Mar 6 at 16:46











      • @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
        Mar 6 at 16:48






      • 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
        Mar 6 at 17:44















      7














      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.






      share|improve this answer




















      • 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
        Mar 6 at 16:44












      • Why do you assume that it's safe to cast: (List<E>) itemIter?

        – ernest_k
        Mar 6 at 16:46











      • @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
        Mar 6 at 16:48






      • 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
        Mar 6 at 17:44













      7












      7








      7







      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.






      share|improve this answer















      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 7 at 5:34

























      answered Mar 6 at 16:17









      AndronicusAndronicus

      3,98621429




      3,98621429







      • 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
        Mar 6 at 16:44












      • Why do you assume that it's safe to cast: (List<E>) itemIter?

        – ernest_k
        Mar 6 at 16:46











      • @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
        Mar 6 at 16:48






      • 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
        Mar 6 at 17:44












      • 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
        Mar 6 at 16:44












      • Why do you assume that it's safe to cast: (List<E>) itemIter?

        – ernest_k
        Mar 6 at 16:46











      • @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
        Mar 6 at 16:48






      • 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
        Mar 6 at 17:44







      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
      Mar 6 at 16:44






      @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
      Mar 6 at 16:44














      Why do you assume that it's safe to cast: (List<E>) itemIter?

      – ernest_k
      Mar 6 at 16:46





      Why do you assume that it's safe to cast: (List<E>) itemIter?

      – ernest_k
      Mar 6 at 16:46













      @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
      Mar 6 at 16:48





      @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
      Mar 6 at 16:48




      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
      Mar 6 at 17:44





      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
      Mar 6 at 17:44











      5














      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.






      share|improve this answer























      • can't tell why this is not a lot higher :|

        – Eugene
        2 days 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
        2 days ago















      5














      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.






      share|improve this answer























      • can't tell why this is not a lot higher :|

        – Eugene
        2 days 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
        2 days ago













      5












      5








      5







      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.






      share|improve this answer













      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.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Mar 6 at 18:26









      HolgerHolger

      169k23238453




      169k23238453












      • can't tell why this is not a lot higher :|

        – Eugene
        2 days 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
        2 days ago

















      • can't tell why this is not a lot higher :|

        – Eugene
        2 days 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
        2 days ago
















      can't tell why this is not a lot higher :|

      – Eugene
      2 days ago





      can't tell why this is not a lot higher :|

      – Eugene
      2 days 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
      2 days 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
      2 days ago











      4














      You can abuse reduction:



      Stream<E> stream = ...;
      System.out.println(stream
      .reduce("",(out,e) ->
      out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
      + e));





      share|improve this answer





























        4














        You can abuse reduction:



        Stream<E> stream = ...;
        System.out.println(stream
        .reduce("",(out,e) ->
        out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
        + e));





        share|improve this answer



























          4












          4








          4







          You can abuse reduction:



          Stream<E> stream = ...;
          System.out.println(stream
          .reduce("",(out,e) ->
          out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
          + e));





          share|improve this answer















          You can abuse reduction:



          Stream<E> stream = ...;
          System.out.println(stream
          .reduce("",(out,e) ->
          out + (out.isEmpty() ? e.getClass().getSimpleName()+"n" : "")
          + e));






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 6 at 16:38

























          answered Mar 6 at 16:20









          Benjamin UrquhartBenjamin Urquhart

          1196




          1196





















              0














              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]





              share|improve this answer


















              • 1





                requires you to always reset the value though, and will not work in a multi thread environment

                – Lino
                Mar 6 at 16:52















              0














              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]





              share|improve this answer


















              • 1





                requires you to always reset the value though, and will not work in a multi thread environment

                – Lino
                Mar 6 at 16:52













              0












              0








              0







              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]





              share|improve this answer













              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]






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Mar 6 at 16:33









              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
                Mar 6 at 16:52












              • 1





                requires you to always reset the value though, and will not work in a multi thread environment

                – Lino
                Mar 6 at 16:52







              1




              1





              requires you to always reset the value though, and will not work in a multi thread environment

              – Lino
              Mar 6 at 16:52





              requires you to always reset the value though, and will not work in a multi thread environment

              – Lino
              Mar 6 at 16:52











              0














              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);

              )
              ...





              share|improve this answer




















              • 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
                Mar 6 at 16:36












              • @nullpointer you're right, I've edited my answer to use StreamSupport

                – Lino
                Mar 6 at 16:46











              • The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

                – Holger
                Mar 6 at 17:45















              0














              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);

              )
              ...





              share|improve this answer




















              • 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
                Mar 6 at 16:36












              • @nullpointer you're right, I've edited my answer to use StreamSupport

                – Lino
                Mar 6 at 16:46











              • The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

                – Holger
                Mar 6 at 17:45













              0












              0








              0







              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);

              )
              ...





              share|improve this answer















              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);

              )
              ...






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Mar 6 at 16:45

























              answered Mar 6 at 16:32









              LinoLino

              9,78822043




              9,78822043







              • 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
                Mar 6 at 16:36












              • @nullpointer you're right, I've edited my answer to use StreamSupport

                – Lino
                Mar 6 at 16:46











              • The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

                – Holger
                Mar 6 at 17:45












              • 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
                Mar 6 at 16:36












              • @nullpointer you're right, I've edited my answer to use StreamSupport

                – Lino
                Mar 6 at 16:46











              • The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

                – Holger
                Mar 6 at 17:45







              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
              Mar 6 at 16:36






              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
              Mar 6 at 16:36














              @nullpointer you're right, I've edited my answer to use StreamSupport

              – Lino
              Mar 6 at 16:46





              @nullpointer you're right, I've edited my answer to use StreamSupport

              – Lino
              Mar 6 at 16:46













              The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

              – Holger
              Mar 6 at 17:45





              The action passed to peek will be executed in the processing order which is not guaranteed to be the Stream’s encounter order.

              – Holger
              Mar 6 at 17:45











              0














              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)));





              share|improve this answer



























                0














                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)));





                share|improve this answer

























                  0












                  0








                  0







                  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)));





                  share|improve this answer













                  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)));






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 6 at 16:59









                  ernest_kernest_k

                  23.4k42749




                  23.4k42749



























                      draft saved

                      draft discarded
















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      Identity Server 4 is not redirecting to Angular app after login2019 Community Moderator ElectionIdentity Server 4 and dockerIdentityserver implicit flow unauthorized_clientIdentityServer Hybrid Flow - Access Token is null after user successful loginIdentity Server to MVC client : Page Redirect After loginLogin with Steam OpenId(oidc-client-js)Identity Server 4+.NET Core 2.0 + IdentityIdentityServer4 post-login redirect not working in Edge browserCall to IdentityServer4 generates System.NullReferenceException: Object reference not set to an instance of an objectIdentityServer4 without HTTPS not workingHow to get Authorization code from identity server without login form

                      2005 Ahvaz unrest Contents Background Causes Casualties Aftermath See also References Navigation menue"At Least 10 Are Killed by Bombs in Iran""Iran"Archived"Arab-Iranians in Iran to make April 15 'Day of Fury'"State of Mind, State of Order: Reactions to Ethnic Unrest in the Islamic Republic of Iran.10.1111/j.1754-9469.2008.00028.x"Iran hangs Arab separatists"Iran Overview from ArchivedConstitution of the Islamic Republic of Iran"Tehran puzzled by forged 'riots' letter""Iran and its minorities: Down in the second class""Iran: Handling Of Ahvaz Unrest Could End With Televised Confessions""Bombings Rock Iran Ahead of Election""Five die in Iran ethnic clashes""Iran: Need for restraint as anniversary of unrest in Khuzestan approaches"Archived"Iranian Sunni protesters killed in clashes with security forces"Archived

                      Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme