How to get the first element while continue streaming?












13















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











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

    – AlikElzin-kilaka
    7 hours ago
















13















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











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

    – AlikElzin-kilaka
    7 hours ago














13












13








13


3






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









Rakete1111

35k1083119




35k1083119










asked 10 hours ago









AlikElzin-kilakaAlikElzin-kilaka

18.7k15126202




18.7k15126202













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

    – AlikElzin-kilaka
    10 hours ago











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

    – AlikElzin-kilaka
    7 hours ago



















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

    – AlikElzin-kilaka
    10 hours ago











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

    – AlikElzin-kilaka
    7 hours ago

















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

– AlikElzin-kilaka
10 hours ago





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

– AlikElzin-kilaka
10 hours ago













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

– AlikElzin-kilaka
7 hours ago





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

– AlikElzin-kilaka
7 hours ago












7 Answers
7






active

oldest

votes


















8














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











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

    – Andrew Tobilko
    9 hours ago











  • @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

    – Holger
    9 hours ago






  • 1





    By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

    – Holger
    8 hours ago



















5














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













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

    – ernest_k
    9 hours ago











  • @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

    – Andronicus
    9 hours ago






  • 1





    Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

    – Holger
    8 hours ago



















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
      9 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
      10 hours ago













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

      – Lino
      9 hours ago











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

      – Holger
      8 hours ago



















    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









        8














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











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

          – Andrew Tobilko
          9 hours ago











        • @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

          – Holger
          9 hours ago






        • 1





          By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

          – Holger
          8 hours ago
















        8














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











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

          – Andrew Tobilko
          9 hours ago











        • @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

          – Holger
          9 hours ago






        • 1





          By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

          – Holger
          8 hours ago














        8












        8








        8







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









        Andrew Tobilko

        27.9k104388




        27.9k104388










        answered 10 hours ago









        RuslanRuslan

        3,030822




        3,030822













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

          – Lino
          9 hours ago











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

          – Andrew Tobilko
          9 hours ago











        • @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

          – Holger
          9 hours ago






        • 1





          By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

          – Holger
          8 hours ago



















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

          – Lino
          9 hours ago











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

          – Andrew Tobilko
          9 hours ago











        • @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

          – Holger
          9 hours ago






        • 1





          By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

          – Holger
          8 hours ago

















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

        – Lino
        9 hours ago





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

        – Lino
        9 hours ago













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

        – Andrew Tobilko
        9 hours ago





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

        – Andrew Tobilko
        9 hours ago













        @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

        – Holger
        9 hours ago





        @Lino combine this answer which performs an action for the first element (but also consumes it) and this answer which will push the first item back after examining it and you have the necessary tools to construct such an operation.

        – Holger
        9 hours ago




        1




        1





        By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

        – Holger
        8 hours ago





        By the way, it’s preferable to use StreamEx.of(itemIter.spliterator()), which may carry additional meta information to the stream (depending on the actual Iterable), potentially improving the performance.

        – Holger
        8 hours ago













        5














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













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

          – ernest_k
          9 hours ago











        • @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

          – Andronicus
          9 hours ago






        • 1





          Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

          – Holger
          8 hours ago
















        5














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













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

          – ernest_k
          9 hours ago











        • @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

          – Andronicus
          9 hours ago






        • 1





          Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

          – Holger
          8 hours ago














        5












        5








        5







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

























        answered 10 hours ago









        AndronicusAndronicus

        3,45921429




        3,45921429








        • 1





          @AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.

          – Andrew Tobilko
          9 hours ago













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

          – ernest_k
          9 hours ago











        • @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

          – Andronicus
          9 hours ago






        • 1





          Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

          – Holger
          8 hours ago














        • 1





          @AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.

          – Andrew Tobilko
          9 hours ago













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

          – ernest_k
          9 hours ago











        • @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

          – Andronicus
          9 hours ago






        • 1





          Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

          – Holger
          8 hours ago








        1




        1





        @AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.

        – Andrew Tobilko
        9 hours ago







        @AlikElzin-kilaka please don't ask about the memory implications :) To me, it's obvious that none of Stream API solutions will outdo the simple loop approach mentioned by you (I'd go with a fori loop, though) in any way (performance, readability, maintenance). I honestly don't understand why you want streams here.

        – Andrew Tobilko
        9 hours ago















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

        – ernest_k
        9 hours ago





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

        – ernest_k
        9 hours ago













        @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

        – Andronicus
        9 hours ago





        @ernest_k it doesn't really matter, I don't know the context (what itemIter really is). Let's just treat it as a pseudocode, that can be compiled, just to show the idea :)

        – Andronicus
        9 hours ago




        1




        1





        Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

        – Holger
        8 hours ago





        Well, it doesn’t even compile. Since objects are not an Iterable and an Iterator at the same time, you can’t cast it to List and expect it to also have a next() method. Once you fixed this, you don’t need the questionable type cast: E firstElement = itemIter.iterator().next(); Stream<E> stream = StreamSupport.stream(itemIter.spliterator(), false);

        – Holger
        8 hours ago











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

























            answered 10 hours ago









            Benjamin UrquhartBenjamin Urquhart

            905




            905























                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
                  9 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
                  9 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 10 hours ago









                Mohammad AdilMohammad Adil

                39.4k1471100




                39.4k1471100








                • 1





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

                  – Lino
                  9 hours ago














                • 1





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

                  – Lino
                  9 hours ago








                1




                1





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

                – Lino
                9 hours ago





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

                – Lino
                9 hours ago











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













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

                  – Lino
                  9 hours ago











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

                  – Holger
                  8 hours ago
















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













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

                  – Lino
                  9 hours ago











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

                  – Holger
                  8 hours ago














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

























                answered 10 hours ago









                LinoLino

                9,76922043




                9,76922043








                • 1





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

                  – nullpointer
                  10 hours ago













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

                  – Lino
                  9 hours ago











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

                  – Holger
                  8 hours ago














                • 1





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

                  – nullpointer
                  10 hours ago













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

                  – Lino
                  9 hours ago











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

                  – Holger
                  8 hours ago








                1




                1





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

                – nullpointer
                10 hours ago







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

                – nullpointer
                10 hours ago















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

                – Lino
                9 hours ago





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

                – Lino
                9 hours ago













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

                – Holger
                8 hours ago





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

                – Holger
                8 hours ago











                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 9 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 8 hours ago









                            HolgerHolger

                            168k23238453




                            168k23238453






























                                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

                                If I really need a card on my start hand, how many mulligans make sense? [duplicate]

                                Alcedinidae

                                Can an atomic nucleus contain both particles and antiparticles? [duplicate]