Коллекции и структуры данных#
В этом разделе описаны основные типы коллекций в JEXL: списки, массивы, множества, карты и кортежи. Вы узнаете, как объявлять коллекции, добавлять и удалять элементы, а также выполнять основные операции для работы с данными. Материал содержит практические примеры для каждого типа коллекций.
Список#
Список является изменяемым типом данных (mutable). Это значит, что можно добавлять и удалять элементы, а также изменять существующие.
Исходный массив для примера:
var mvStock = ["P-1001", "P-1002", "P-1003", ...];
Основные операции
Объявление списков:
var mvStockApproachOne = [...];
Добавление элементов (только для mutable):
mvStock.add("P-1004");
Получение элементов:
mvStock[0]; // способ 1
mvStock.get(0); // способ 2
Проверка наличия элемента:
mvStock.contains("P-1002"); // возвращает true/false
Удаление элементов (только для mutable):
mvStock.remove("P-1002");
Размер списка:
mvStock.size(); // возвращает количество элементов
Проверка на пустоту:
mvStock.isEmpty(); // возвращает true/false
Поиск индекса элемента:
mvStock.indexOf("P-1001"); // возвращает индекс или -1
Замена элемента (только для mutable):
mvStock.set(0, "newElement"); // способ 1
mvStock[0] = "newElement"; // способ 2
Объединение списков (только для mutable):
var listUnion = [1,2,3, ...];
mvStockApproachOne.addAll(listUnion);
Очистка списка (только для mutable):
mvStock.clear(); // удаляет все элементы
Массив#
Массив — это неизменяемая (immutable) структура данных с фиксированным размером. Вы не можете добавлять и удалять элементы, но можно изменять значения существующих элементов (если они сами по себе изменяемы).
Исходный массив для примера:
var mvStock = ["P-1001", "P-1002", "P-1003"];
Основные операции
Объявление массива:
var mvStockApproachOne = [];
var mvStockApproachTwo = [1, 2, 3];
Получение элементов:
mvStock[0]; // способ 1
mvStock.get(0); // способ 2
Проверка наличия элемента:
mvStock.contains("P-1002"); // возвращает true/false
Размер списка:
mvStock.size(); // количество элементов
Поиск индекса элемента:
mvStock.indexOf("P-1001"); // возвращает индекс или -1
Множество#
Доступны только mutable (изменяемые) множества. Основные операции
Создание множества:
var setData = {"P-1001", "P-1002", "P-1003"}; // Множество с элементами
var setEmptyData = {}; // Пустое множество
Добавление элементов:
setData.add("P-1004"); // Добавление одного элемента
setData.addAll({"P-1005", "P-1006"}); // Добавление другого множества
setData.addAll(["P-1007", "P-1008"]); // Добавление элементов из списка
При добавлении списка порядок элементов множества сбивается.
Проверка и получение элементов:
var exists = setData.contains("P-1001"); // Проверка наличия → true/false
Удаление элементов:
setData.remove("P-1001"); // Удаление по значению
setData.clear(); // Полная очистка множества
Работа с размерами:
var size = setData.size(); // Количество элементов
var isEmpty = setData.isEmpty(); // Проверка на пустоту → true/false
Операции с множествами:
// Пересечение (оставляет только общие элементы)
setData.retainAll({"P-1005", "P-1006"});
// Разность (удаляет элементы другого множества)
setData.removeAll({"P-1002", "P-1003"});
Карта#
Далее в примерах будем работать с этой картой:
var mapData = {"bwhasError" : 11, "svKeyTransaction" : 21}; // объявление словаря
Внимание
Если в карте добавляется несколько элементов с одинаковыми ключами, то последнее значение перезапишет предыдущее. В словаре все ключи уникальны, и каждому ключу соответствует только одно значение.
var mapData = {
"bwhasError": 11,
"svKeyTransaction": 21, // Это значение будет перезаписано
"svKeyTransaction": 22 // Останется только это
};
// Итоговая карта: {"bwhasError": 11, "svKeyTransaction": 22}
Основные операции со словарями
Получение и добавление элемента:
mapData.e = 5; // добавление нового ключа (способ 1)
mapData.put("c", 3); // добавление нового ключа (способ 2)
mapData["d"] = 4; // добавление нового ключа (способ 3)
var approachTwo = mapData.bwhasError; // получение значения по ключу (способ 1)
var approachOne = mapData.get("bwhasError"); // получение значения по ключу (способ 2)
var approachThree = mapData["bwhasError"]; // получение значения по ключу (способ 3)
Получить и добавить значению по ключу можно тремя способами: через точку, квадратные скобки, метод get.
Точечная нотация работает только с ключами, которые являются валидными идентификаторами (без пробелов, дефисов, начинающиеся с буквы).
Для ключей со спецсимволами (тире, пробелы, точки) используйте квадратные скобки.
Методы put()/get() работают всегда, но требуют больше кода.
Пример с ограничениями:
var mvStock = {"P-1001" : 1, "P-1002" : 2, "P-1003" : 3};
var nCode = mvStock.P-1001; // Дефис воспримется как оператор
Проверка наличия ключа:
mapData.containsKey("bwhasError"); // возвращает true/false
Удаление элемента:
mapData.remove("bwhasError"); // удаляет пару "ключ-значение" по ключу
Размер словаря:
mapData.size(); // количество пар "ключ-значение"
Получение всех ключей:
mapData.keySet(); // возвращает массив ключей (например,["bwhasError", "svKeyTransaction"])
Получение всех значений:
mapData.values(); // возвращает массив значений (например, [11, 21])
Проверка на пустоту:
mapData.isEmpty(); // true, если карта пустая
Изменение значения по ключу:
mapData["bwhasError"] = 10; // присваивает новое значение ключу
Добавление новой пары «ключ-значение»:
mapData["newKey"] = 42; // добавляет новый ключ с значением
Очистка словаря:
mapData.clear(); // удаляет все элементы
Объединение словарей:
var newMap = {"key1": 1, "key2": 2};
mapData.addAll(newMap); // добавляет все пары из newMap в mapData (существующие ключи перезаписываются)
Операция entrySet:
var mapData = {"bwhasError" : 11, "svKeyTransaction" : 21};
var setMap = mapData.entrySet(); // Получаем множество пар ключ-значение
for (entry : setMap) { // Итерация по всем элементам (парам ключ-значение)
var key = entry.getKey(); // Получить ключ текущей пары
var value = entry.getValue(); // Получить значение текущей пары
}
Возвращает множество(Set) пар ключ-значение - объектов Map.Entry.
Каждый Entry содержит:
getKey() - уникальный ключ;
getValue() - соответствующее значение.
Перебор значений идет в обратном порядке.
Когда использовать entrySet():
Когда нужны и ключи, и значения в цикле.
Для модификации значений через entry.setValue().
Для получения «снимка» всех данных Map
Получение ключа по значению
Нет встроенной функции для получения ключа по значению, но можно написать свою локальную функцию для этой цели:
// Получения ключа по значению
var findKeysByValue = function(map, targetValue) {
var matchedKeys = [...]; // Сюда будем складывать подходящие ключи
for (let key : map.keySet()) { // Перебираем каждый ключ
if (map[key] == targetValue) { // Если значение по ключу совпадает с искомым
return key; // Добавляем ключ в результат
}
}
return matchedKeys; // Возвращаем найденные ключи в виде списка
};
var keyListForValue = findKeysByValue(mapData, 11);
dialogs.showMessage(toString(keyListForValue));
По такому же принципу можно реализовать удаление ключа по значению.
Кортеж#
Кортежи — это неизменяемые (immutable) структуры данных, которые позволяют хранить фиксированное количество элементов разных типов. Они полезны, когда нужно временно сгруппировать данные без создания отдельного класса.
В JEXL отсутствует встроенный тип данных Кортеж (Tuple), но его можно эмулировать с помощью интеграции с Scala. Кортежи Tuple2 — это естественный способ передать такие данные из JEXL в Scala-код.
var tuple2 = (v1, v2) -> { return new(`scala.Tuple2`, v1, v2); };
new(scala.Tuple2, …) — создает экземпляр Scala-кортежа, используя JVM-интеграцию.
Функция принимает 2 аргумента и возвращает неизменяемую пару (v1, v2).
В Scala стандартные кортежи (Tuple) ограничены 22 элементами (до Tuple22):
var tuple22 = (v1, v2, v3,v4, v5, v6,v7, v8, v9,v10, v11, v12, v13, v14, v15,v16, v17, v18,v19, v20, v21,v22) -> {
return new(`scala.Tuple22`, v1, v2, v3,v4, v5, v6,v7, v8, v9,v10, v11, v12, v13, v14, v15,v16, v17, v18,v19, v20, v21,v22);
};
dialogs.showMessage(toString(tuple22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)));
Чтобы передавать параметры в Scala-коллекции, используем asScala():
// Массив пар [Имя_параметра, Значение]
var tuple2Params = asScala([
tuple2("npInParam1", 10l), // Параметр 1 (Long)
tuple2("npInParam2", 125l), // Параметр 2 (Long)
tuple2("npInParam3", 1000l), // Параметр 3 (Long)
... // Остальные элементы (если есть)
]);
Особенности:
asScala() — преобразует JEXL-массив в Scala-коллекцию;
каждый элемент коллекции — кортеж («имя», значение).
Кортежи неизменяемы, что гарантирует:
параметры не поменяются случайно во время выполнения процедуры;
нет риска коллизий в многопоточных сценариях.