#java-8 #hashmap #java-stream
#java-8 #хэш-карта #java-stream
Вопрос:
Я пытаюсь отфильтровать исходную карту путем сравнения с картой условий, которая имеет только наборы ключей с идентификатором. Основываясь на карте условий, я хочу выполнить фильтрацию по исходной карте.
Исходная карта, которая у меня есть, является,
Map<Integer, AppFeatureDTO> appFeatureMap = new TreeMap<>();
что приведет к подобному,
{
"101": {
"id": 101,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
}
}
},
"102": {
"id": 102,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
}
}
},
"103": {
"id": 103,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
},
"2": {
"id": 2,
"title": "Title Value",
"desc": "Description Value"
},
"3": {
"id": 3,
"title": "Title Value",
"desc": "Description Value"
},
"4": {
"id": 4,
"title": "Title Value",
"desc": "Description Value"
}
}
}
}
и соответствующие классы являются:
class AppFeatureDTO {
private int id;
private Map<Integer, AppSubFeatureDTO> subFeature;
}
class AppSubFeatureDTO{
private int id;
private String title;
private String description;
}
тогда у меня есть карта фильтра,
Map<Integer, FeatureDTO> conditionFilterMap = new TreeMap<>();
что приводит к подобному,
{
"101": {
"id": 101,
"subFeature": {
"1": {
"id": 1,
}
}
},
"103": {
"id": 103,
"subFeature": {
"2": {
"id": 2
},
"4": {
"id": 4
}
}
}
}
соответствующие классы для карты фильтров являются,
class FeatureDTO {
private int id;
private Map<Integer, SubFeatureDTO> subFeature;
}
class SubFeatureDTO{
private int id;
}
Я хочу отфильтровать результирующую карту, используя conditionFilterMap, например,
{
"101": {
"id": 101,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
}
}
},
"103": {
"id": 103,
"subFeature": {
"2": {
"id": 2,
"title": "Title Value",
"desc": "Description Value"
},
"4": {
"id": 4,
"title": "Title Value",
"desc": "Description Value"
}
}
}
}
Я использую spring ModelMapper для копирования AppFeatureDTO
в FeatureDTO
. Но, фильтруя карту, я не получил подсказки.
Не могли бы вы, пожалуйста, подсказать, как получить resultMap
с помощью Java 8?
Даже я не мог представить простое решение, также использующее Java 7 или 6.
Ответ №1:
Предполагая, что ключ карты совпадает с полем id:
Map<Integer, AppFeatureDTO> resultMap = conditionFilterMap.values().stream()
.map(FeatureDTO::getId)
.map(appFeatureMap::get)
.collect(Collectors.toMap(AppFeatureDTO::getId, a -> new AppFeatureDTO(a.getId(),
conditionFilterMap.get(a.getId()).getSubFeature().values().stream()
.map(SubFeatureDTO::getId)
.map(a.getSubFeature()::get)
.collect(Collectors.toMap(AppSubFeatureDTO::getId, x -> x)))));
Если вам нужно TreeMap
, добавьте аргументы (a, b) -> a, TreeMap::new
в Collectors.toMap
вызовы.
Беспоточная версия на самом деле выглядит ничуть не хуже:
Map<Integer, AppFeatureDTO> resultMap = new TreeMap<>();
for (FeatureDTO f : conditionFilterMap.values()) {
AppFeatureDTO a = appFeatureMap.get(f.getId());
Map<Integer, AppSubFeatureDTO> resultSub = new TreeMap<>();
for (SubFeatureDTO s : f.getSubFeature().values()) {
resultSub.put(s.getId(), a.getSubFeature().get(s.getId()));
}
resultMap.put(a.getId(), new AppFeatureDTO(a.getId(), resultSub));
}
Комментарии:
1. В этом также есть ошибка, можете ли вы просмотреть ее один раз. согласно 4-й строке первого фрагмента, вы передаете конструктору значение, подобное ключу. Это опечатка? или мне нужно создать конструктор?
2. @Shakthi вы можете переписать код для работы без такого конструктора, но это стало бы намного сложнее, поэтому рекомендуется создать такой конструктор.
3. @Shakthi Если у вас нет конструктора, создаете ли вы экземпляры с помощью
new AppFeatureDTO()
и вызываетеsetWhatever
для установки значений полей? Если это так, я бы настоятельно рекомендовал добавить в ваши классы базовые конструкторы, которые принимают значения полей в качестве параметров, большинство IDE могут сгенерировать их для вас.