How to get the first element while continue streaming?












12















I have a stream of generic items. I'd like to print the class name of the first item + the toString() of all the items.



If I had an Iterable, it would look like this:



Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}


Any idea if I can do this on a stream (Stream<T>) with stream api? Thanks.



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










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
    4 hours ago











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

    – AlikElzin-kilaka
    1 hour ago
















12















I have a stream of generic items. I'd like to print the class name of the first item + the toString() of all the items.



If I had an Iterable, it would look like this:



Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}


Any idea if I can do this on a stream (Stream<T>) with stream api? Thanks.



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










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
    4 hours ago











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

    – AlikElzin-kilaka
    1 hour ago














12












12








12


2






I have a stream of generic items. I'd like to print the class name of the first item + the toString() of all the items.



If I had an Iterable, it would look like this:



Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}


Any idea if I can do this on a stream (Stream<T>) with stream api? Thanks.



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










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


Any idea if I can do this on a stream (Stream<T>) with stream api? Thanks.



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







java java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 26 mins ago









Rakete1111

35k1083119




35k1083119










asked 5 hours ago









AlikElzin-kilakaAlikElzin-kilaka

18.7k15126202




18.7k15126202













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

    – AlikElzin-kilaka
    4 hours ago











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

    – AlikElzin-kilaka
    1 hour ago



















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

    – AlikElzin-kilaka
    4 hours ago











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

    – AlikElzin-kilaka
    1 hour ago

















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

– AlikElzin-kilaka
4 hours ago





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

– AlikElzin-kilaka
4 hours ago













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

– AlikElzin-kilaka
1 hour ago





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

– AlikElzin-kilaka
1 hour ago












7 Answers
7






active

oldest

votes


















7














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
    4 hours ago











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

    – Andrew Tobilko
    4 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
    3 hours ago






  • 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
    3 hours 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














    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


























    • Hmmm... is there an API to duplicate a stream? What would be the memory implications?

      – AlikElzin-kilaka
      4 hours ago






    • 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
      4 hours ago













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

      – ernest_k
      4 hours ago











    • @AlikElzin-kilaka I've edited the answer with that info

      – Andronicus
      4 hours ago






    • 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
      3 hours ago



















    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
      4 hours ago



















    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
      4 hours ago













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

      – Lino
      4 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
      3 hours ago



















    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














      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























        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-to-get-the-first-element-while-continue-streaming%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        7 Answers
        7






        active

        oldest

        votes








        7 Answers
        7






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        7














        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
          4 hours ago











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

          – Andrew Tobilko
          4 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
          3 hours ago






        • 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
          3 hours ago
















        7














        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
          4 hours ago











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

          – Andrew Tobilko
          4 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
          3 hours ago






        • 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
          3 hours ago














        7












        7








        7







        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 4 hours ago









        Andrew Tobilko

        27.9k104388




        27.9k104388










        answered 4 hours ago









        RuslanRuslan

        3,020822




        3,020822













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

          – Lino
          4 hours ago











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

          – Andrew Tobilko
          4 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
          3 hours ago






        • 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
          3 hours ago



















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

          – Lino
          4 hours ago











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

          – Andrew Tobilko
          4 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
          3 hours ago






        • 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
          3 hours ago

















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

        – Lino
        4 hours ago





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

        – Lino
        4 hours ago













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

        – Andrew Tobilko
        4 hours ago





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

        – Andrew Tobilko
        4 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
        3 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
        3 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
        3 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
        3 hours 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 4 hours ago

























            answered 4 hours ago









            Benjamin UrquhartBenjamin Urquhart

            905




            905























                4














                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


























                • Hmmm... is there an API to duplicate a stream? What would be the memory implications?

                  – AlikElzin-kilaka
                  4 hours ago






                • 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
                  4 hours ago













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

                  – ernest_k
                  4 hours ago











                • @AlikElzin-kilaka I've edited the answer with that info

                  – Andronicus
                  4 hours ago






                • 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
                  3 hours ago
















                4














                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


























                • Hmmm... is there an API to duplicate a stream? What would be the memory implications?

                  – AlikElzin-kilaka
                  4 hours ago






                • 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
                  4 hours ago













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

                  – ernest_k
                  4 hours ago











                • @AlikElzin-kilaka I've edited the answer with that info

                  – Andronicus
                  4 hours ago






                • 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
                  3 hours ago














                4












                4








                4







                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















                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 2 hours ago

























                answered 4 hours ago









                AndronicusAndronicus

                3,47921429




                3,47921429













                • Hmmm... is there an API to duplicate a stream? What would be the memory implications?

                  – AlikElzin-kilaka
                  4 hours ago






                • 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
                  4 hours ago













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

                  – ernest_k
                  4 hours ago











                • @AlikElzin-kilaka I've edited the answer with that info

                  – Andronicus
                  4 hours ago






                • 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
                  3 hours ago



















                • Hmmm... is there an API to duplicate a stream? What would be the memory implications?

                  – AlikElzin-kilaka
                  4 hours ago






                • 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
                  4 hours ago













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

                  – ernest_k
                  4 hours ago











                • @AlikElzin-kilaka I've edited the answer with that info

                  – Andronicus
                  4 hours ago






                • 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
                  3 hours ago

















                Hmmm... is there an API to duplicate a stream? What would be the memory implications?

                – AlikElzin-kilaka
                4 hours ago





                Hmmm... is there an API to duplicate a stream? What would be the memory implications?

                – AlikElzin-kilaka
                4 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
                4 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
                4 hours ago















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

                – ernest_k
                4 hours ago





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

                – ernest_k
                4 hours ago













                @AlikElzin-kilaka I've edited the answer with that info

                – Andronicus
                4 hours ago





                @AlikElzin-kilaka I've edited the answer with that info

                – Andronicus
                4 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
                3 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
                3 hours ago











                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
                  4 hours ago
















                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
                  4 hours ago














                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 4 hours ago









                Mohammad AdilMohammad Adil

                39.4k1471100




                39.4k1471100








                • 1





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

                  – Lino
                  4 hours ago














                • 1





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

                  – Lino
                  4 hours ago








                1




                1





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

                – Lino
                4 hours ago





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

                – Lino
                4 hours ago











                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
                  4 hours ago













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

                  – Lino
                  4 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
                  3 hours ago
















                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
                  4 hours ago













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

                  – Lino
                  4 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
                  3 hours ago














                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 4 hours ago

























                answered 4 hours ago









                LinoLino

                9,76922043




                9,76922043








                • 1





                  In that sense, I guess the code in question would be much better even if the iterable is defined. Keeping in mind there is nothing like itemIter.stream() available up front.

                  – nullpointer
                  4 hours ago













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

                  – Lino
                  4 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
                  3 hours ago














                • 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
                  4 hours ago













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

                  – Lino
                  4 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
                  3 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
                4 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
                4 hours ago















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

                – Lino
                4 hours ago





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

                – Lino
                4 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
                3 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
                3 hours ago











                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 4 hours ago









                    ernest_kernest_k

                    23.4k42649




                    23.4k42649























                        0














                        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




























                          0














                          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


























                            0












                            0








                            0







                            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 2 hours ago









                            HolgerHolger

                            168k23237453




                            168k23237453






























                                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-to-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

                                Why is a white electrical wire connected to 2 black wires?

                                Waikiki

                                What are all the squawk codes?