web-dev-qa-db-ja.com

Spring式言語-Java 8forEachまたはリスト上のストリーム

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))
10
Mateusz Sobczak

SpELはJavaではなく、別の言語です。頭字語はSpringExpressionの略ですLanguage

Java8ラムダを理解しないため、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));

(しかし、それはあまり役に立ちません)。

ストリームを使用できますが、ラムダを使用しない単純なメソッドでのみ使用できます...

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));

[〜#〜]編集[〜#〜]

ただし、ラムダを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]

EDIT2

または、より一般的に...

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;
    }

}
12
Gary Russell