Получить строку из карты внутри карты Java 8 - PullRequest
0 голосов
/ 07 сентября 2018

Как вы думаете, это лучший способ найти значение на карте внутри другой карты.

    Map <String, String> map1 = new HashMap<>();

    map1.put("map1|1", "1.1");
    map1.put("map1|2", "1.2");
    map1.put("map1|3", "1.3");
    map1.put("map1|4", "1.4");

    Map <String, String> map2 = new HashMap<>();

    map2.put("map2|1", "2.1");
    map2.put("map2|2", "2.2");
    map2.put("map2|3", "2.3");
    map2.put("map2|4", "2.4");


    Map<String, Map> mapOfMaps = new HashMap<>();

    mapOfMaps.put("MAP|map1", map1);
    mapOfMaps.put("MAP|map2", map2);

Теперь, если мне нужно, значение «MAP | map2» (внутри mapOfMaps) и «map2 | 3» (внутри map2) будет равно «2.3»

Я пытался сделать что-то вроде:

System.out.println("x="+getValue(mapOfMaps,"MAP|map2", "map2|4"));

public static String getValue (Map<String, Map> map,String mapfind, String val) {

     Map<Object, Object> mp = map.entrySet().stream()
                .filter(x -> x.getKey().equals(mapfind))
                .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));

     System.out.println("--------"+mp);

     return (String) mp.get(val);
 }

но результат:

--------{MAP|map2={map2|1=2.1, map2|4=2.4, map2|2=2.2, map2|3=2.3}}
x=null

Можете ли вы помочь мне с некоторыми идеями?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Вместо объявления mapOfMaps его необработанным типом его следует определить как

Map<String, Map<String, String>> mapOfMaps = new HashMap<>();

Соответствующий метод getValue будет выглядеть так:

  public static String getValue(Map<String, Map<String, String>> mapOfMaps, String mapfind, String val) {
    Map<String, String> innerMap = mapOfMaps.get(mapfind);
    return innerMap != null ?
      innerMap.get(val) :
      null;
  }

Используя Optional, мы можем написать это следующим образом:

  public static String getValue(Map<String, Map<String, String>> mapOfMaps, String mapfind, String val) {
    return Optional.ofNullable(mapOfMaps.get(mapfind))
      .map(m -> m.get(val))
      .orElse(null);
  }

Если бы мы сохраняли mapOfMaps объявленным его необработанным типом, мы бы получили в первой версии getValue предупреждение о безопасности типа о непроверенном преобразовании , а во второй версии нам нужно было бы явно привести результат до String. Поскольку мы используем mapOfMaps только для сопоставления String ключей с String значениями, мы должны объявить это соответствующим образом.


Дальнейшее чтение: Что такое необработанный тип и почему мы не должны его использовать?

0 голосов
/ 08 сентября 2018

Я думаю, что самый простой способ получить желаемый результат - использовать map.get(mapfind).get(val). Но если вы хотите добиться этого, используя существующий код, вы можете вызвать values() на собранном map и вызвать фильтр, чтобы получить фильтр второго уровня. Ниже приведен фрагмент кода вашего модифицированного метода

public static String getValue(Map<String, Map> map, String mapfind, String val) {
    Map mp = map.entrySet().stream().filter(x -> x.getKey().equals(mapfind))
            .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()))

            .values().stream().filter(y -> y.containsKey(val)).findAny().orElse(null);

    System.out.println("--------" + mp);
    if (mp == null)
        return "";
    return (String) mp.get(val);
}
0 голосов
/ 07 сентября 2018
public static String getValue (Map<String, Map> map,String mapfind, String val) {
    Map childMap = map.get(mapfind);
    if (childMap == null) {
        return null;
    }
    return childMap.containsKey(val) ? childMap.get(val).toString() : null;
}
...