Java 如何创建通用MVEL表达式

Java 如何创建通用MVEL表达式,java,spring,spring-boot,mvel,Java,Spring,Spring Boot,Mvel,我正在为Java对象编写通用MVEL表达式。为了理解这个目的,我举了一个例子 class Student { String name; String rollNo; List<Course> courses; } class Course { String courseName; String facultyName; String fee; String classRoom; } 但如果问题是: 检查学生是否参加了同

我正在为Java对象编写通用MVEL表达式。为了理解这个目的,我举了一个例子

class Student {

   String name;

   String rollNo;

   List<Course> courses;
}

class Course {
   
   String courseName;

   String facultyName;

   String fee;

   String classRoom;
}
但如果问题是: 检查学生是否参加了同一教室的所有课程?

MVEL.eval(" courses[0].classRoom == 'A' ", Student);
但这只检查了一门课程的课堂。但我想检查一个学生的所有课程是否都发生在“a”教室。 我找不到任何资源来解决这个问题。我是MVEL的新手。如果你有任何疑问,请问我


谢谢你

要做到这一点需要几个步骤-你需要使用MVEL变量及其属性

方法如下:

import org.mvel2.MVEL;
导入java.util.List;
导入java.util.ArrayList;
导入java.util.Map;
导入java.util.HashMap;
公共类应用程序{
公共静态void main(字符串[]args){
列出课程=新建ArrayList();
增加(新课程(“数学”、“123”));
增加(新课程(“物理”,“123”));
增加(新课程(“化学”、“123”));
学生=新生(“XYZ”,“3456”,课程);
//检查学生是否提供姓名和学号:
布尔b1=MVEL.eval(“name='XYZ'&&rollNo=='3456',学生,boolean.class”);
布尔b2=MVEL.eval(“name='XYP'&&rollNo=='3456',学生,布尔.class”);
//系统输出打印LN(b1);
//系统输出打印LN(b2);
//检查学生是否参加了同一教室的所有课程:
布尔值allClassesInSameRoom=true;
字符串prevRoom=null;
Map vars=newhashmap();
vars.put(“sameRoom”,所有类别的存储空间);
vars.put(“prevRoom”,prevRoom);
字符串表达式=String.join(“\n”,
“sameRoom=true;”,
“prevRoom=null;”,
“foreach(课程:课程){”,
“如果(sameRoom==true&&prevRoom!=null&&course.教室!=prevRoom){”,
“sameRoom=false;”,
"  }",
“prevRoom=课程教室;”,
"}",
“sameRoom”);
allClassesInSameRoom=MVEL.eval(表达式、学生、变量、布尔.class);
System.out.println(所有类别存储空间);
}
}
首先,我们定义两个Java变量,它们是MVEL脚本中需要的。它们通过Java映射传递给MVEL
eval
操作员:

boolean allClassesInSameRoom=true;
字符串prevRoom=null;
Map vars=newhashmap();
vars.put(“sameRoom”,所有类别的存储空间);
vars.put(“prevRoom”,prevRoom);
然后,我们构建一个字符串,其中包含我们需要使用的MVEL脚本:

String expression=String.join(“\n”,
“sameRoom=true;”,
“prevRoom=null;”,
“foreach(课程:课程){”,
“如果(sameRoom==true&&prevRoom!=null&&course.教室!=prevRoom){”,
“sameRoom=false;”,
"  }",
“prevRoom=课程教室;”,
"}",
“sameRoom”);
最后一行返回
sameRoom
变量

eval
语句组合了我们需要的项目:

allClassesInSameRoom=MVEL.eval(表达式、学生、变量、布尔.class);
请注意,
课程
类需要定义为
公共

公共课{
私有最终字符串courseName;
私人教室;
公共课程(字符串课程名称、字符串教室){
this.courseName=courseName;
这个教室=教室;
}
公共字符串getCourseName(){
返回courseName;
}
公共字符串get教室(){
返回教室;
}
}
可以将MVEL脚本创建为模板,我认为这有助于避免像我在这里所做的那样逐行构建Java字符串的复杂过程

这可能比不使用MVEL简单地检查
student
对象要复杂得多。但是MVEL也支持函数和lambda表达式,所以可能有一些方法可以简化我的方法并简化MVEL脚本


更新

下面是一个更紧凑的示例:

Map rooms=newhashmap();
Map vars2=新的HashMap();
vars2.put(“房间”,房间);
字符串表达式2=String.join(“\n”,
“foreach(课程:课程){”,
“房间。放(当然。教室,当然。教室);”,
"}",
“(rooms.size()==1)?真:假;”;
allClassesInSameRoom=MVEL.eval(表达式2,学生,变量2,布尔.class);
System.out.println(所有类别存储空间);
在本例中,脚本将每个房间名称添加到地图中。重复的房间名称将具有相同的地图键,因此不会增加地图的大小。如果我们最终得到一张只包含一个条目的地图,这意味着只有一个房间用于所有课程


或者,您可以使用Java(Java 8或更高版本)计算学生课程列表中不同房间名称的数量:

导入静态java.util.stream.Collectors.toList;
...
long roomsCount=courses.stream()
.map(Course::get教室)//获取每个课程的教室名称
.collect(toList())//生成这些房间名称的列表
.stream().distinct().count();//计算唯一房间名称的数量

这是一行代码。但由于您的目标是探索和理解MVEL,因此这只是一个旁注。

感谢您的帮助。但表情看起来很复杂。我们能简化一下吗?我们可以做一些类似的事情吗,例如:expression=courses[REGEX].choursel==A。其中正则表达式是正则表达式。要访问列表,您可以使用
课程[5]
()访问列表中的特定项,也可以使用
foreach
运算符
MVEL.eval(" courses[0].classRoom == 'A' ", Student);