Для этого необходимо выполнить несколько шагов: вам нужно будет использовать переменные MVEL и его foreach
оператор. .
Вот подход:
import org.mvel2.MVEL;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
public class App {
public static void main(String[] args) {
List<Course> courses = new ArrayList<>();
courses.add(new Course("Math", "123"));
courses.add(new Course("Physics", "123"));
courses.add(new Course("Chemistry", "123"));
Student student = new Student("XYZ", "3456", courses);
// Check If a student has given name and rollNo:
boolean b1 = MVEL.eval(" name == 'XYZ' && rollNo == '3456' ", student, Boolean.class);
boolean b2 = MVEL.eval(" name == 'XYP' && rollNo == '3456' ", student, Boolean.class);
//System.out.println(b1);
//System.out.println(b2);
// Check If a student attends all the courses in the same classroom:
boolean allClassesInSameRoom = true;
String prevRoom = null;
Map vars = new HashMap();
vars.put( "sameRoom", allClassesInSameRoom );
vars.put( "prevRoom", prevRoom );
String expression = String.join("\n",
"sameRoom = true;",
"prevRoom = null;",
"foreach (course : courses) {",
" if (sameRoom == true && prevRoom != null && course.classRoom != prevRoom) {",
" sameRoom = false;",
" }",
" prevRoom = course.classRoom;",
"}",
"sameRoom");
allClassesInSameRoom = MVEL.eval(expression, student, vars, Boolean.class);
System.out.println(allClassesInSameRoom);
}
}
Сначала мы определяем две переменные Java, которые необходимы в скрипте MVEL. Они передаются оператору МВЭЛ eval
через карту Java:
boolean allClassesInSameRoom = true;
String prevRoom = null;
Map<String, Object> vars = new HashMap<>();
vars.put( "sameRoom", allClassesInSameRoom );
vars.put( "prevRoom", prevRoom );
Затем мы создаем строку, содержащую сценарий MVEL, который нам нужно использовать:
String expression = String.join("\n",
"sameRoom = true;",
"prevRoom = null;",
"foreach (course : courses) {",
" if (sameRoom == true && prevRoom != null && course.classRoom != prevRoom) {",
" sameRoom = false;",
" }",
" prevRoom = course.classRoom;",
"}",
"sameRoom");
Последняя строка возвращает переменную sameRoom
.
Оператор eval
собирает нужные нам элементы:
allClassesInSameRoom = MVEL.eval(expression, student, vars, Boolean.class);
Обратите внимание, что класс Course
должен быть определен как public
:
public class Course {
private final String courseName;
private final String classRoom;
public Course (String courseName, String classRoom) {
this.courseName = courseName;
this.classRoom = classRoom;
}
public String getCourseName() {
return courseName;
}
public String getClassRoom() {
return classRoom;
}
}
Сценарии MVEL можно создавать как шаблоны, что, как мне кажется, может помочь избежать несколько запутанного процесса построчного построения Java String, как я делаю здесь.
Все это может потребовать больше работы, чем простая проверка объекта student
без использования MVEL. Но MVEL также поддерживает функции и лямбда-выражения, так что, вероятно, есть способы рационализировать мой подход и упростить сценарий MVEL.
Обновить
Вот пример, который немного более компактен:
Map<String, String> rooms = new HashMap<>();
Map<String, Object> vars2 = new HashMap<>();
vars2.put( "rooms", rooms );
String expression2 = String.join("\n",
"foreach (course : courses) {",
" rooms.put(course.classRoom, course.classRoom);",
"}",
"(rooms.size() == 1) ? true : false;");
allClassesInSameRoom = MVEL.eval(expression2, student, vars2, Boolean.class);
System.out.println(allClassesInSameRoom);
В этом случае скрипт добавляет каждое имя комнаты на карту. Повторяющиеся названия комнат будут иметь один и тот же ключ карты, поэтому размер карты не увеличится. Если мы получим карту, содержащую только одну запись, это означает, что для всех курсов используется только одна комната.
В качестве альтернативы вы можете подсчитать количество разных названий комнат в списке курсов учащегося с помощью Java (Java 8 или выше):
import static java.util.stream.Collectors.toList;
...
long roomsCount = courses.stream()
.map(Course::getClassRoom) // get the room name from each course
.collect(toList()) // build a list of these room names
.stream().distinct().count(); // count the number of unique room names
Это одна строка кода. Но поскольку ваша цель — изучить и понять MVEL, это просто примечание.
person
andrewjames
schedule
24.12.2020