1

我有字符串,我需要在其中找到括号(), {}[]并使用堆栈来检查正确性,如果有错误则打印错误的位置。因此,我将它们拆分为 char 数组,然后想逐个检查符号,如果它匹配我的地图,则执行我向/从堆栈推送/弹出的方法。

我想象它是这样的:

ParentStack s = new ParentStack();
Map<Character, Method> map = new HashMap<Character, Method>();
map.put('(', s.push('('));
map.put(')', s.pop()); //then check if its opposite 

那么有这样的事情吗?或者我必须使用开关?

4

3 回答 3

1

由于 java 不是函数式编程语言(函数是所谓的一等公民),因此您不能通过引用传递函数。相反,您可以做的是使用一种名为 example 的方法创建一个接口execute()。然后你为你想要的每个函数实现这个接口并将它们放在地图中,在那里你可以很容易地调用它们并执行这些“函数”。

public interface function{
    void execute();
}

并且(在 java 8 中)您的代码可能如下所示:

ParentStack s = new ParentStack();
Map<Character, Method> map = new HashMap<Character, Method>();
map.put('(', (Function) () -> s.push('('));
map.put(')', (Function) () -> s.pop());

有些人甚至会这样写:

map.put('(', () -> s.push('('));

我认为这并不容易阅读,但这是一个偏好问题。

要执行您的Function使用:

map.get('(').execute();
于 2016-02-14T23:46:09.823 回答
0

使用BooleanSupplier而不是Method.

    Stack<Character> s = new Stack<>();
    Map<Character, BooleanSupplier> map = new HashMap<>();
    map.put('(', () -> { s.push('('); return true; });
    map.put(')', () -> !s.isEmpty() && s.pop() == '(');

并像这样检查。

    String str = "((ab)c)";
    int errorAt = -1;
    for (int i = 0; i < str.length(); ++i) {
        char c = str.charAt(i);
        if (map.containsKey(c))
            if (!map.get(c).getAsBoolean()) {
                errorAt = i;
                break;
            }
    }
    if (errorAt == -1 && s.isEmpty())
        System.out.println("OK!");
    else if (errorAt == -1)
        System.out.println("error at " + str.length());  // too few ')'
    else
        System.out.println("error at " + errorAt);  // too many ')'

或者您可以使用 Stream API。

    int errorAt = IntStream.range(0, str.length())
        .filter(i -> map.containsKey(str.charAt(i)))
        .reduce(-1, (p, i) -> p >= 0 || map.get(str.charAt(i)).getAsBoolean() ? p : i);
于 2016-02-15T00:32:16.473 回答
0

您正在调用该方法而不是将其放入地图中。您可以做的是将Runnable接口实例放入地图中。Runnable是没有参数列表和没有返回值的任何方法的 Java 的默认接口。如果您需要参数或返回值,您可能需要查看 package 中的接口java.util.function。例如Supplier<T>有一个返回值和Consumer<T>一个参数。

下面是一个使用 Java 8 lambda 表达式的示例:

ParentStack s = new ParentStack();
Map<Character, Runnable> map = new HashMap<Character, Runnable>();
map.put('(', () -> s.push('('));
map.put(')', () -> s.pop());

以及用法:

map.get('(').run();

run()方法由Runnable接口声明,并将调用您放入地图的方法。不要被不同的名称所迷惑。

于 2016-02-15T00:04:57.170 回答