You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8中如何用Streams和Lambda更优雅实现带if-else的方法?

More Idiomatic Java 8 Implementation for Bracket Validation

Great question! Your current Java 8 attempt uses forEach but misses critical logic (like checking for an empty stack before popping, and the ability to early-exit when invalid) — plus forEach doesn’t play nicely with early termination, which is why it feels almost identical to the Java 7 loop. Let’s fix that and make it more idiomatic with Java 8 stream features.

First, the Problem with Your Current Java 8 Code

Your version doesn’t handle cases where we encounter a closing bracket with an empty stack, and it can’t return false early (since forEach can’t interrupt the stream). This would throw a NoSuchElementException if you pass an invalid string like ")", which the Java 7 code correctly handles by returning false.

A Clean, Efficient Java 8 Solution

Instead of forEach, use allMatch — this method short-circuits (stops processing as soon as it hits a false), which mimics the early return behavior of your original loop. Here’s how to implement it:

private static boolean execute(String expression) {
    Deque<Character> stack = new ArrayDeque<>();
    
    // Use chars() to get an IntStream of character codes, then map to char
    boolean allValid = expression.chars()
            .mapToObj(c -> (char) c)
            .allMatch(c -> {
                if (isOpenToken(c)) {
                    stack.push(c);
                    return true; // Keep processing further characters
                }
                // Check if stack is empty or brackets don't match
                if (stack.isEmpty() || !matches(stack.pop(), c)) {
                    return false; // Short-circuit: invalid, stop processing immediately
                }
                return true; // Valid so far, continue
            });
    
    // After all characters are processed, stack must be empty to be valid
    return allValid && stack.isEmpty();
}

Why This Works Better

  • Short-circuiting: allMatch stops processing immediately when it encounters an invalid character, just like your original return false in the Java 7 loop.
  • Cleaner stream pipeline: We use expression.chars() directly instead of converting to a char[] first, which is more concise and reads better.
  • Full logic preservation: This implementation maintains all validation checks from your Java 7 code, including the final stack-empty check.

Alternative: Using Reduce (For Immutable State)

If you prefer immutable state (though it’s less efficient here since we have to copy the stack each time), you can wrap the stack and validation status in a helper class and use reduce:

// Helper class to hold validation state
private static class ValidationState {
    private final Deque<Character> stack;
    private final boolean isValid;

    private ValidationState(Deque<Character> stack, boolean isValid) {
        this.stack = stack;
        this.isValid = isValid;
    }

    // Process a single character and return a new state
    private ValidationState process(char c) {
        if (!isValid) return this; // Skip processing if already invalid
        
        if (isOpenToken(c)) {
            Deque<Character> newStack = new ArrayDeque<>(stack);
            newStack.push(c);
            return new ValidationState(newStack, true);
        }
        
        if (stack.isEmpty() || !matches(stack.pop(), c)) {
            return new ValidationState(stack, false);
        }
        
        return new ValidationState(stack, true);
    }
}

private static boolean execute(String expression) {
    ValidationState finalState = expression.chars()
            .mapToObj(c -> (char) c)
            .reduce(new ValidationState(new ArrayDeque<>(), true),
                    ValidationState::process,
                    (state1, state2) -> {
                        // Parallel processing isn't practical here, so throw an error if used
                        throw new UnsupportedOperationException("Parallel processing not supported for bracket validation");
                    });
    
    return finalState.isValid && finalState.stack.isEmpty();
}

This approach is more functional but less efficient than the allMatch version because it copies the stack for each character. Stick with allMatch for most cases — it’s faster and closer to the original logic.

内容的提问来源于stack exchange,提问作者theyCallMeJun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:27:31