javajava-streamoption-typefindfirst

Resume processing of a Java Stream after running findFirst()


Given a simple list of strings:

List<String> strings = Arrays.asList("Mary", "James", "Jim", "Camilla");

I'd like to process each item of the list with a anotherMethod() method, however the first item shall be processed additionally by someMethod().

I've tried something like this:

List<String> strings = Arrays.asList("Mary", "James", "Jim", "Camilla");

var result = strings.stream()
     .findFirst()
     .map(myString -> someMethod(myString))
     // "resume" stream
     .map(myString -> anotherMethod(myString))
     .toList();     

Is there a way to handle such a scenario using a Stream or something similar?


Update 1

Here is an example to help you better understand the motivation behind my question.

List<String> strings = Arrays.asList("Mary", "James", "Jim", "Camilla");

public String someMethod(String s) {
  return s.toUpperCase();
}

public String anotherMethod(String s) {
  return s.toLowerCase();
}

The final result shall be a List<String> with the following elements, that is, only the first element is converted to upper-case while all other elements are converted to lower-case.

"MARY", "james", "jim", "camilla"


Solution

  • findFirst collapses the stream to an Optional<String>, and there is nothing to resume.

    Optional<String> mary = Stream.of("Mary", "James", "Jim", "Camilla").findFirst();
    

    Do you want to reduce the stream to only one element? Then the method limit(1) might be what you are looking for and then concat it with a copy where you skip(1) the element.

    List<String> strings = Arrays.asList("Mary", "James", "Jim", "Camilla");
    List<String> result = Stream.concat(
          strings.stream()
            .limit(1)
            .map(this::someMethod),
          strings.stream()
            .skip(1))
            .map(this::anotherMethod)
         ).toList();
    

    Edit: After Update 1:

    You wouldn't want to apply toLowerCase() to the first element after you applied toUpperCase().