How to rewrite dropWhile in java 8?

132 views Asked by At

As you know, dropWhile for streams was introduced in java 9. But if the target of the project is java 8, you can't use it.

Example code:

public static String getParameterValueOrDefault(String[] args, String paramName, String defaultVal) {
    return Arrays.stream(args).sequential().dropWhile(arg->!arg.equals("/"+paramName) && !arg.equals("-"+paramName)).skip(1).findFirst().orElseGet(()->defaultVal);
}

What I want is an equivalent lambda expression written in java 8.

2

There are 2 answers

1
PatoOta On

I found this way:

public static String getParameterValueOrDefault(String[] args, String paramName, String defaultVal) {
    MutableBoolean foundParam = new MutableBoolean(false);
    return Arrays.stream(args).sequential().peek(arg->foundParam.value = foundParam.value || arg.equals("/"+paramName) || arg.equals("-"+paramName)).filter(arg->foundParam.value).skip(1).findFirst().orElseGet(()->defaultVal);
}

Where MutableBoolean is:

private static class MutableBoolean {
    boolean value;
    public MutableBoolean(boolean value) {
        this.value = value;
    }
}
2
Holger On

You can use

public static String getParameterValueOrDefault(
                     String[] args, String paramName, String defaultVal) {

    int ix = IntStream.range(0, args.length)
        .filter(i -> args[i].matches("[/-]" + Pattern.quote(paramName)))
        .map(i -> i + 1)
        .findFirst().orElse(args.length);
    return ix < args.length? args[ix]: defaultVal;
}

The matches approach is for convenience, if you prefer compact code. If you want an efficient check, you may instead use:

public static String getParameterValueOrDefault(
                     String[] args, String paramName, String defaultVal) {

    int ix = IntStream.range(0, args.length)
        .filter(i -> {
            String arg = args[i];
            return arg.length() == paramName.length() + 1 && arg.endsWith(paramName)
                && (arg.charAt(0) == '-' || arg.charAt(0) == '/');
        })
        .map(i -> i + 1)
        .findFirst().orElse(args.length);
    return ix < args.length? args[ix]: defaultVal;
}