Получить HashMapsValues ​​из вложенного HashMap> фильтруется по списку <String> - PullRequest
1 голос
/ 05 октября 2019

У меня есть вложенная строка HashMap и список объектов. У объекта есть свойство String для сопоставления со значениями внутреннего HashMap.

Я пытаюсь найти один вкладыш, используя stream() и Collectors для приведенного ниже кода Java

HashMap<String, HashMap<String, String>>PartDetailsHMap=new HashMap<String, HashMap<String, String>>()
List<Part> partList=new ArrayList<Part>();


for(int i=0;i<partList.size();i++)
    String partId = partList.get(i).getPropertyValue("part_id");
    for(HashMap< String, String> PartPropsHMap:PartDetailsHMap.values())
    {
        if(PartPropsHMap.containsValue(itemId))
        {
            collectingPartMap.put(partList.get(i), PartPropsHMap);
            break;
        }
    }
}

При необходимости я могу извлечь свойство String в List<String>.

Искать один вкладыш, используя stream().

Ответы [ 2 ]

3 голосов
/ 05 октября 2019

Примерно так должно работать:

    Map<String, Map<String, String>> PartDetailsHMap = new HashMap<>();
    List<Part> partList = new ArrayList<>();

    Map<Part, Map<String, String>> collectingPartMap = partList.stream()
      .map(part -> PartDetailsHMap.values()
        .stream()
        .filter(partPropsHMap -> partPropsHMap.containsValue(part.getPropertyValue("part_id")))
        .findFirst()
        .map(partPropsHMap -> new SimpleEntry<Part, Map>(part, partPropsHMap))
        .get()
      )
      .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));

Я использовал SimpleEntry класс в AbstractMap для переноса контекста Part вместе с картой, которую мы нашли, к следующемуоперация - collect.

Предостережение: я чувствую, если вариант без потоков будет чище и сделает свою работу, я бы пошел с этим. Учитывая, что манипуляции, которые вам здесь нужны, довольно сложны, в долгосрочной перспективе было бы полезно сделать их более читабельными, чем что-то умное.

0 голосов
/ 05 октября 2019

Альтернативный подход, слегка улучшающий текущий ответ, может состоять в том, чтобы не выполнять get без проверки isPresent. Это может быть достигнуто с помощью filter и map

Map<Part, Map<String, String>> collectingPartMap = partList.stream()
        .map(part -> partDetailsHMap.values().stream()
                .filter(innerMap -> innerMap.containsValue(part.getPartId())) // notice 'getPartId' for the access
                .findFirst()
                .map(firstInnerMap -> new AbstractMap.SimpleEntry<>(part, firstInnerMap)))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
...