#java #data-structures #java-8
#java #структуры данных #java-8
Вопрос:
Создание комбинаций из нескольких столбцов в объект массива, состоящий из комбинации значений и имени столбца в java? Так что каждый объект будет состоять из массива Object (column name, value)
.
У меня есть информация, хранящаяся по имени столбца и значениям внутри этого столбца. Например:
Region Store State
west Reliance california
east Dmart newyork
В основном для приведенного выше структура JSON выглядит следующим образом
[
{
"type": "Region",
//more fields
"filterValues": [
{
"name": "west"
//more fields
},
{
"name": "east"
}
]
},
{
"type": "Store",
"filterValues": [
{
"name": "Reliance"
},
{
"name": "Dmart"
}
]
},
{
"type": "State",
"filterValues": [
{
"name": "california"
},
{
"name": "newyork"
}
]
}
]
Как я могу преобразовать приведенную выше структуру в следующие комбинации:
Region west | Store Reliance | State california
Region west | Store Reliance | State newyork
Region west | Store Dmart | State california
Region west | Store Dmart | State newyork
.
.
.
Таким образом, структура объекта будет следующей.
[
{
"values": [
{
"type": "Region",
"name": "west"
},
{
"type": "Store",
"name": "Reliance"
},
{
"type": "State",
"name": "california"
}
]
},
{
"values": [
{
"type": "Region",
"name": "west"
},
{
"type": "Store",
"name": "Reliance"
},
{
"type": "State",
"name": "newyork"
}
]
}
]
Как я могу реализовать эту структуру данных?
Я пытался сначала создать map, в котором имя столбца будет key
, а значения в этом столбце будут частью value
as
Map<String, List<String>> typeBOsMap = attributes
.stream()
.collect(Collectors.toMap(Attribute::getType,
attribute -> attribute.getFilterValues()
.stream()
.map(AttributeFilters::getFilterValue)
.collect(Collectors.toList()))
);
Но после этого я снова застрял на том, как комбинация будет создана из этой карты?
Комментарии:
1. всегда существует три типа или может быть несколько?
2. Может быть несколько типов. Это динамическое. 1/2/3 или более.
3. Способ заключается в использовании рекурсии. Рекурсивно перейдите к типу и повторите значение типа и добавьте в список.
Ответ №1:
Сначала преобразуйте typeBOsMap
в List<Map.Entry<String, List<String>>>
List<Map.Entry<String, List<String>>> list = typeBOsMap.entrySet().stream().collect(Collectors.toList());
Затем рекурсивно переставить все возможные комбинации
List<List<Map.Entry<String, String>>> permute(List<Map.Entry<String, List<String>>> list,
int index, List<Map.Entry<String, String>> now) {
if (index >= list.size()) {
return Arrays.asList(now);
}
Map.Entry<String, List<String>> entry = list.get(index);
List<List<Map.Entry<String, String>>> res = new ArrayList<>();
for (String value : entry.getValue()) {
List<Map.Entry<String, String>> newList = new ArrayList<>(now);
newList.add(new AbstractMap.SimpleEntry<>(entry.getKey(), value));
res.addAll(permute(list, index 1, newList));
}
return res;
}
Вы можете вызвать эту функцию с помощью list
List<List<Map.Entry<String, String>>> data = permute(list, 0, Collections.emptyList());
Вывод:
[State=california, Region=west, Store=Reliance]
[State=california, Region=west, Store=Dmart]
[State=california, Region=east, Store=Reliance]
[State=california, Region=east, Store=Dmart]
[State=newyork, Region=west, Store=Reliance]
[State=newyork, Region=west, Store=Dmart]
[State=newyork, Region=east, Store=Reliance]
[State=newyork, Region=east, Store=Dmart]
Онлайн-демонстрация здесь
Комментарии:
1. Вы пробовали это решение? Не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы?
2. Это круто. Именно то, что я хотел. Позже в коде я только что сделал
stream.map(-> construct object)
. при построении объекта я также выполняю итерациюinner map
для полученияkey,values
. Я думаю, что имя функции следует переименовать вcombine
, что скажете?3. Это полностью зависит от личного вкуса.