如何将方法放在地图中?
How to put method in map?
我有字符串,我需要在其中找到方括号 ()
、{}
、[]
并使用堆栈检查正确性,如果有错误则打印错误的位置。所以我将它们拆分为 char 数组,然后想逐个检查符号,如果它与我的映射匹配,则执行我的 pushing/popping to/from 堆栈方法。
我是这样想象的:
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
所以有这样的东西吗?或者我必须使用开关?
由于 java 不是函数式编程语言(这里的函数就是所谓的 first-class citizens),您不能通过引用传递函数。您可以做的是创建一个接口,其中包含一个名为 execute()
的方法。然后你为每个你想拥有的功能实现这个接口并将它们放在映射中,在那里你可以轻松地调用它们并执行这些 "functions".
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();
您正在调用该方法,而不是将其放入地图中。您可以做的是将 Runnable
接口的实例放入地图中。 Runnable
是 Java 任何没有参数列表和 return 值的方法的默认接口。如果您需要参数或 return 值,您可能需要查看包 java.util.function
中的接口。例如 Supplier<T>
有一个 return 值,而 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
接口声明,将调用您放入地图的方法。不要被不同的名字搞糊涂了。
使用 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);
我有字符串,我需要在其中找到方括号 ()
、{}
、[]
并使用堆栈检查正确性,如果有错误则打印错误的位置。所以我将它们拆分为 char 数组,然后想逐个检查符号,如果它与我的映射匹配,则执行我的 pushing/popping to/from 堆栈方法。
我是这样想象的:
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
所以有这样的东西吗?或者我必须使用开关?
由于 java 不是函数式编程语言(这里的函数就是所谓的 first-class citizens),您不能通过引用传递函数。您可以做的是创建一个接口,其中包含一个名为 execute()
的方法。然后你为每个你想拥有的功能实现这个接口并将它们放在映射中,在那里你可以轻松地调用它们并执行这些 "functions".
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();
您正在调用该方法,而不是将其放入地图中。您可以做的是将 Runnable
接口的实例放入地图中。 Runnable
是 Java 任何没有参数列表和 return 值的方法的默认接口。如果您需要参数或 return 值,您可能需要查看包 java.util.function
中的接口。例如 Supplier<T>
有一个 return 值,而 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
接口声明,将调用您放入地图的方法。不要被不同的名字搞糊涂了。
使用 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);