How do I get the first element while continue streaming?2019 Community Moderator ElectionCan I duplicate a...

How to draw tikz paths composed only of horizontal, vertical and diagonal segments?

How do you make a gun that throws swords?

Should I use HTTPS on a domain that will only be used for redirection?

The need of reserving one's ability in job interviews

How can friction do no work in case of pure rolling?

Is there a math equivalent to the conditional ternary operator?

Number of folds to form a cube, using a square paper?

How to chmod files that have a specific set of permissions

How does insurance birth control work?

Why would the IRS ask for birth certificates or even audit a small tax return?

What is brightness?

The (Easy) Road to Code

How to concatenate two command in shell

Can a Tiny Servant be used as a messenger?

Are Wave equations equivalent to Maxwell equations?

Searching for a string that contains the file name

How do I deal with being envious of my own players?

Practical reasons to have both a large police force and bounty hunting network?

Specific Chinese carabiner QA?

ToC header appears in next chapter

How can I handle a player who pre-plans arguments about my rulings on RAW?

Where is this quote about overcoming the impossible said in "Interstellar"?

Are there other characters in the Star Wars universe who had damaged bodies and needed to wear an outfit like Darth Vader?

What is a term for a function that when called repeatedly, has the same effect as calling once?



How do I get the first element while continue streaming?



2019 Community Moderator ElectionCan I duplicate a Stream in Java 8?How to iterate with foreach loop over java 8 streamHow to match stream elements but return false if non exists?Performing specific operation on first element of list using Java8 streamingHow to get an enum value from a string value in Java?Efficiency of Java “Double Brace Initialization”?Java Security: Illegal key size or default parameters?Ways to iterate over a list in JavaHow to Convert a Java 8 Stream to an Array?Find first element by predicateRemove and collect elements with Java streamsStream Way to get index of first element matching booleanStream of cartesian product of other streams, each element as a List?Java Stream groupingBy where key is an element in a sublist












15















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



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



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


Can I do this on a stream (Stream<T>) with the stream API?



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










share|improve this question

























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

    – AlikElzin-kilaka
    21 hours ago











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

    – AlikElzin-kilaka
    18 hours ago











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

    – Ilmari Karonen
    5 hours ago
















15















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



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



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


Can I do this on a stream (Stream<T>) with the stream API?



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










share|improve this question

























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

    – AlikElzin-kilaka
    21 hours ago











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

    – AlikElzin-kilaka
    18 hours ago











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

    – Ilmari Karonen
    5 hours ago














15












15








15


4






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



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



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


Can I do this on a stream (Stream<T>) with the stream API?



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










share|improve this question
















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



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



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


Can I do this on a stream (Stream<T>) with the stream API?



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







java java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 4 hours ago









Peter Mortensen

13.7k1986113




13.7k1986113










asked 21 hours ago









AlikElzin-kilakaAlikElzin-kilaka

18.7k15126203




18.7k15126203













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

    – AlikElzin-kilaka
    21 hours ago











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

    – AlikElzin-kilaka
    18 hours ago











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

    – Ilmari Karonen
    5 hours ago



















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

    – AlikElzin-kilaka
    21 hours ago











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

    – AlikElzin-kilaka
    18 hours ago











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

    – Ilmari Karonen
    5 hours ago

















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

– AlikElzin-kilaka
21 hours ago





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

– AlikElzin-kilaka
21 hours ago













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

– AlikElzin-kilaka
18 hours ago





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

– AlikElzin-kilaka
18 hours ago













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

– Ilmari Karonen
5 hours ago





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

– Ilmari Karonen
5 hours ago












7 Answers
7






active

oldest

votes


















10














There is StreamEx library that extends standard Java's Stream API. Using StreamEx.of(Iterator) and peekFirst :



StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);





share|improve this answer


























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

    – Lino
    21 hours ago






  • 1





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

    – Andrew Tobilko
    21 hours ago











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

    – Holger
    20 hours ago






  • 1





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

    – Holger
    20 hours ago



















7














Native solution: Stream in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.



Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:



Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);


Edit



There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.






share|improve this answer





















  • 1





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

    – Andrew Tobilko
    21 hours ago













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

    – ernest_k
    21 hours ago











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

    – Andronicus
    21 hours ago






  • 1





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

    – Holger
    20 hours ago



















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














    If your starting point is a Stream and you want to retain all of its properties and the laziness, the following solution will do:



    public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
    boolean parallel = stream.isParallel();
    Spliterator<E> sp = stream.spliterator();
    return StreamSupport.stream(() -> {
    if(sp.getExactSizeIfKnown() == 0) return sp;
    Stream.Builder<E> b = Stream.builder();
    if(!sp.tryAdvance(b.andThen(c))) return sp;
    return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
    }, sp.characteristics(), parallel);
    }


    E.g. when you use it with



    List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
    Stream<String> stream = forFirst(
    list.stream().filter(s -> s.startsWith("b")),
    s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
    ).map(String::toUpperCase);
    list.add(1, "blah");
    System.out.println(stream.collect(Collectors.joining(" | ")));


    it will print



    blah (String)
    BLAH | BAR | BAZ


    demonstrating that the processing will not start before commencing the terminal operation (collect), hence reflecting the preceding update to the source List.






    share|improve this answer
























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

      – Eugene
      5 hours ago











    • @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

      – Holger
      3 hours ago



















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













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

      – Lino
      21 hours ago











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

      – Holger
      20 hours ago



















    0














    You can also use an boolean atomic reference:



    AtomicReference<Boolean> first = new AtomicReference<Boolean>(Boolean.TRUE);
    stream.forEach(e ->
    System.out.println("First == " + first.getAndUpdate(b -> false)));





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55027574%2fhow-do-i-get-the-first-element-while-continue-streaming%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      10














      There is StreamEx library that extends standard Java's Stream API. Using StreamEx.of(Iterator) and peekFirst :



      StreamEx.of(itemIter.iterator())
      .peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
      .forEach(System.out::println);





      share|improve this answer


























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

        – Lino
        21 hours ago






      • 1





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

        – Andrew Tobilko
        21 hours ago











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

        – Holger
        20 hours ago






      • 1





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

        – Holger
        20 hours ago
















      10














      There is StreamEx library that extends standard Java's Stream API. Using StreamEx.of(Iterator) and peekFirst :



      StreamEx.of(itemIter.iterator())
      .peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
      .forEach(System.out::println);





      share|improve this answer


























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

        – Lino
        21 hours ago






      • 1





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

        – Andrew Tobilko
        21 hours ago











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

        – Holger
        20 hours ago






      • 1





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

        – Holger
        20 hours ago














      10












      10








      10







      There is StreamEx library that extends standard Java's Stream API. Using StreamEx.of(Iterator) and peekFirst :



      StreamEx.of(itemIter.iterator())
      .peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
      .forEach(System.out::println);





      share|improve this answer















      There is StreamEx library that extends standard Java's Stream API. Using StreamEx.of(Iterator) and peekFirst :



      StreamEx.of(itemIter.iterator())
      .peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
      .forEach(System.out::println);






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 21 hours ago









      Andrew Tobilko

      28k104388




      28k104388










      answered 21 hours ago









      RuslanRuslan

      3,050823




      3,050823













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

        – Lino
        21 hours ago






      • 1





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

        – Andrew Tobilko
        21 hours ago











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

        – Holger
        20 hours ago






      • 1





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

        – Holger
        20 hours ago



















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

        – Lino
        21 hours ago






      • 1





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

        – Andrew Tobilko
        21 hours ago











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

        – Holger
        20 hours ago






      • 1





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

        – Holger
        20 hours ago

















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

      – Lino
      21 hours ago





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

      – Lino
      21 hours ago




      1




      1





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

      – Andrew Tobilko
      21 hours ago





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

      – Andrew Tobilko
      21 hours ago













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

      – Holger
      20 hours ago





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

      – Holger
      20 hours ago




      1




      1





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

      – Holger
      20 hours ago





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

      – Holger
      20 hours ago













      7














      Native solution: Stream in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.



      Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:



      Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
      E firstElement = itemIter.next();
      stream.foreach(...);


      Edit



      There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.






      share|improve this answer





















      • 1





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

        – Andrew Tobilko
        21 hours ago













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

        – ernest_k
        21 hours ago











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

        – Andronicus
        21 hours ago






      • 1





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

        – Holger
        20 hours ago
















      7














      Native solution: Stream in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.



      Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:



      Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
      E firstElement = itemIter.next();
      stream.foreach(...);


      Edit



      There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.






      share|improve this answer





















      • 1





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

        – Andrew Tobilko
        21 hours ago













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

        – ernest_k
        21 hours ago











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

        – Andronicus
        21 hours ago






      • 1





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

        – Holger
        20 hours ago














      7












      7








      7







      Native solution: Stream in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.



      Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:



      Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
      E firstElement = itemIter.next();
      stream.foreach(...);


      Edit



      There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.






      share|improve this answer















      Native solution: Stream in Java is not reusable. This means, that consuming stream can be done only once. If you get the first element from a stream, you can iterate over it one more time.



      Workaround would be to create another stream same as the first one or getting the first item and then creating a stream, something like that:



      Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
      E firstElement = itemIter.next();
      stream.foreach(...);


      Edit



      There is not really any way to "copy" a stream, you need to keep an iterator / collection. More about it here. When it comes to memory once stream is exhausted, it can be collected by garbage collector as there is no use from it. Stream itself does not take more space than iterator it originates from. Bear in mind, that streams can be potentially infinite. Elements currently manipulated are stored in memory.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 8 hours ago

























      answered 21 hours ago









      AndronicusAndronicus

      3,52921429




      3,52921429








      • 1





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

        – Andrew Tobilko
        21 hours ago













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

        – ernest_k
        21 hours ago











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

        – Andronicus
        21 hours ago






      • 1





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

        – Holger
        20 hours ago














      • 1





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

        – Andrew Tobilko
        21 hours ago













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

        – ernest_k
        21 hours ago











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

        – Andronicus
        21 hours ago






      • 1





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

        – Holger
        20 hours ago








      1




      1





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

      – Andrew Tobilko
      21 hours ago







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

      – Andrew Tobilko
      21 hours ago















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

      – ernest_k
      21 hours ago





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

      – ernest_k
      21 hours ago













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

      – Andronicus
      21 hours ago





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

      – Andronicus
      21 hours ago




      1




      1





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

      – Holger
      20 hours ago





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

      – Holger
      20 hours ago











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

























          answered 21 hours ago









          Benjamin UrquhartBenjamin Urquhart

          905




          905























              4














              If your starting point is a Stream and you want to retain all of its properties and the laziness, the following solution will do:



              public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
              boolean parallel = stream.isParallel();
              Spliterator<E> sp = stream.spliterator();
              return StreamSupport.stream(() -> {
              if(sp.getExactSizeIfKnown() == 0) return sp;
              Stream.Builder<E> b = Stream.builder();
              if(!sp.tryAdvance(b.andThen(c))) return sp;
              return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
              }, sp.characteristics(), parallel);
              }


              E.g. when you use it with



              List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
              Stream<String> stream = forFirst(
              list.stream().filter(s -> s.startsWith("b")),
              s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
              ).map(String::toUpperCase);
              list.add(1, "blah");
              System.out.println(stream.collect(Collectors.joining(" | ")));


              it will print



              blah (String)
              BLAH | BAR | BAZ


              demonstrating that the processing will not start before commencing the terminal operation (collect), hence reflecting the preceding update to the source List.






              share|improve this answer
























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

                – Eugene
                5 hours ago











              • @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

                – Holger
                3 hours ago
















              4














              If your starting point is a Stream and you want to retain all of its properties and the laziness, the following solution will do:



              public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
              boolean parallel = stream.isParallel();
              Spliterator<E> sp = stream.spliterator();
              return StreamSupport.stream(() -> {
              if(sp.getExactSizeIfKnown() == 0) return sp;
              Stream.Builder<E> b = Stream.builder();
              if(!sp.tryAdvance(b.andThen(c))) return sp;
              return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
              }, sp.characteristics(), parallel);
              }


              E.g. when you use it with



              List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
              Stream<String> stream = forFirst(
              list.stream().filter(s -> s.startsWith("b")),
              s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
              ).map(String::toUpperCase);
              list.add(1, "blah");
              System.out.println(stream.collect(Collectors.joining(" | ")));


              it will print



              blah (String)
              BLAH | BAR | BAZ


              demonstrating that the processing will not start before commencing the terminal operation (collect), hence reflecting the preceding update to the source List.






              share|improve this answer
























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

                – Eugene
                5 hours ago











              • @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

                – Holger
                3 hours ago














              4












              4








              4







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









              HolgerHolger

              168k23238453




              168k23238453













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

                – Eugene
                5 hours ago











              • @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

                – Holger
                3 hours ago



















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

                – Eugene
                5 hours ago











              • @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

                – Holger
                3 hours ago

















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

              – Eugene
              5 hours ago





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

              – Eugene
              5 hours ago













              @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

              – Holger
              3 hours ago





              @Eugene because posted two hours after the other answers and being placed at the end in the default ordering… nothing to worry about

              – Holger
              3 hours ago











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









              Mohammad AdilMohammad Adil

              39.5k1471100




              39.5k1471100








              • 1





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

                – Lino
                21 hours ago














              • 1





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

                – Lino
                21 hours ago








              1




              1





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

              – Lino
              21 hours ago





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

              – Lino
              21 hours ago











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













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

                – Lino
                21 hours ago











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

                – Holger
                20 hours ago
















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













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

                – Lino
                21 hours ago











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

                – Holger
                20 hours ago














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

























              answered 21 hours ago









              LinoLino

              9,76822043




              9,76822043








              • 1





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

                – nullpointer
                21 hours ago













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

                – Lino
                21 hours ago











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

                – Holger
                20 hours ago














              • 1





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

                – nullpointer
                21 hours ago













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

                – Lino
                21 hours ago











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

                – Holger
                20 hours ago








              1




              1





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

              – nullpointer
              21 hours ago







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

              – nullpointer
              21 hours ago















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

              – Lino
              21 hours ago





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

              – Lino
              21 hours ago













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

              – Holger
              20 hours ago





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

              – Holger
              20 hours ago











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









                  ernest_kernest_k

                  23.4k42649




                  23.4k42649






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55027574%2fhow-do-i-get-the-first-element-while-continue-streaming%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Why does my Macbook overheat and use so much CPU and energy when on YouTube?Why do so many insist on using...

                      How to prevent page numbers from appearing on glossaries?How to remove a dot and a page number in the...

                      Puerta de Hutt Referencias Enlaces externos Menú de navegación15°58′00″S 5°42′00″O /...