Spring Expression Language - Java 8 forEach 或 stream on list

2022-09-04 20:34:18

是否可以在 SpEL 中列出 stream 或 forEach?例如:

List<String> x = new LinkedList<>(Arrays.asList("A","AAB"));
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(x);
parser.parseExpression("x.stream().map(x -> x.replaceAll(\"A\", \"B\")).collect(Collectors.toList())").getValue(context))

答案 1

SpEL不是Java,它是一种不同的语言;首字母缩略词代表春季表达语言

它不理解Java8 lambdas,所以无法解析。x -> ...

此外,静态方法使用 T 运算符调用。

所以,这有效...

List<String> x = new LinkedList<>(Arrays.asList("A","AAB"));
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("stream().collect(T(java.util.stream.Collectors).toList())");
System.out.println(expression.getValue(x));

(但它不是很有用)。

您可以使用流,但只能使用不采用 lambda 的简单方法...

Expression expression = parser.parseExpression("stream().findFirst().get()");
Expression expression = parser.parseExpression("stream().count()");

List<String> x = new LinkedList<>(Arrays.asList("A","AAB", "A"));
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("stream().distinct().collect(T(java.util.stream.Collectors).toList())");
System.out.println(expression.getValue(x));

编辑

但是,您可以将lambda注册为 SpEL ,因此这可以正常工作...#functions

public class So48840190Application {

    public static void main(String[] args) throws Exception {
        List<String> x = new LinkedList<>(Arrays.asList("A","AAB", "A"));
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext ec = new StandardEvaluationContext();
        ec.registerFunction("aToB", So48840190Application.class.getMethod("aToB"));
        Expression expression = parser.parseExpression(
                "stream().map(#aToB()).collect(T(java.util.stream.Collectors).toList())");
        System.out.println(expression.getValue(ec, x));
    }

    public static Function<String, String> aToB() {
        return s -> s.replaceAll("A", "B");
    }

}

[B, BBB, B]

编辑2

或者,更一般地说...

public class So48840190Application {

    public static void main(String[] args) throws Exception {
        List<String> x = new LinkedList<>(Arrays.asList("A","AAB", "A"));
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext ec = new StandardEvaluationContext();
        ec.registerFunction("replaceAll",
                So48840190Application.class.getMethod("replaceAll", String.class, String.class));
        ec.registerFunction("toLowerCase",
                So48840190Application.class.getMethod("toLowerCase"));
        Expression expression = parser.parseExpression(
                "stream().map(#replaceAll('A', 'B')).map(#toLowerCase()).collect(T(java.util.stream.Collectors).toList())");
        System.out.println(expression.getValue(ec, x));
    }

    public static Function<String, String> replaceAll(String from, String to) {
        return s -> s.replaceAll(from, to);
    }

    public static Function<String, String> toLowerCase() {
        return String::toLowerCase;
    }

}

答案 2

您可以在MVEL中使用循环。见 https://github.com/XhinLiang/arthas-mvel

$ count = 1
@Integer[1]
$ for (int i =0; i < 100; i++) { count = count + 1;}
null
$ count
@Integer[101]

推荐