Java 8 Stream: Find first element after element

Viewed 2084

I have this list ["z", "1", "3", "x", "y", "00", "x", "y", "4"] that I need to get the first Integer element after the String 00 in this case 4. I am using Java 8 streams but any other method is welcome. Here is my starter code

myList.stream()
      // Remove any non-Integer characters
      .filter((str) -> !"x".equals(str) && !"y".equals(str) && !"z".equals(str))
      .findFirst()
      .orElse("");

That starts me off by removing all non-Integer Strings but gives me 1. Now what I need is to get 4 which is the first element after 00. What should I add to the filter?

7 Answers

Got from the comment.

 String result = myList.stream().skip(myList.indexOf("00") + 1)
        .filter((str) -> !"x".equals(str) && !"y".equals(str) && !"z".equals(str))
        .findFirst()
        .orElse("");

A simple for loop, perhaps. A lot more readable then a stream expression, also more general, since strings like 'x' and 'y' are not hard coded into it.

boolean found00 = false;
int intAfter00 = -1;
for(String str: myList) {
    if("00".equals(str)) {
       found00 = true; //from this point we look for an integer
       continue;
    }
    if(found00) { //looking for an integer
       try {
           intAfter00 = Integer.parseInt(str);
       } catch(Exception e) {
          continue; //this was not an integer
       }
       break;
    }
}
//If intAfter00 is still -1 here then we did not found an integer after 00

You can try below code.

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class Main {

    public static void main(String[] args) {

        List<String> list = Arrays.asList("z", "1", "3", "x", "y", "00", "x", "y", "4");

        String str = "00";

        Optional<String> dataOptional = list.stream().skip(list.indexOf(str)+1).filter(s -> {
            try {
                Integer.parseInt(s);
                return true;
            } catch (NumberFormatException n) {
                return false;
            }
        }).findFirst();

        if (dataOptional.isPresent()) {
            System.out.println("Data is :: " + dataOptional.get());
        } else {
            System.out.println("No integer present after given string");
        }

    }
}

Make sure str is present in list otherwise it will return first integer from the list.

int index = myList.indexOf("00");
String result =myList.stream.skip(index).filter(str->isInteger(str)).findFirst().orElse(null);

private boolean isInteger(String str){
 try{
   Integer.parseInt(str);
   return true;
 } catch (NumberFormatException e) {
   return false;
 }
 }

You can do as follows using streams:

String result=myList.subList(myList.indexOf("00")+1, myList.size()).stream().filter(string->string.matches("\\d+")).findFirst().get();

This solution gives you a good result even if you are using strings rather than x, y, z.

If you don't have the index of list at this moment. You could do something like this

int count = 0;

Stream.of("z", "1", "3", "x", "y", "00", "98", "y", "4")
.peek(element -> {
    if (element.equals("00") || count > 0 && isNumber(element))
        count++;
}).filter(element -> isNumber(element) && count == 3).findFirst().orElse(null);

private boolean isNumber(String element) {
    return element.matches("\\d+");
};

Try it: Suppose you have a list

String[] v = {"z", "1", "3", "x", "y", "00", "x", "y", "4", "5", "y", "7"};

Now find first element after an element:

String result = Stream.of(v).filter(e-> e.matches("^(\\d+)")).dropWhile(e-> !e.contains("00")).skip(1).findFirst().orElse("");
System.out.println(result);
Related