如何展平HashMap?

时间:2019-01-14 14:51:08

标签: java dictionary hash java-8 flatten

我以这种形式嵌套了HashMap

{key1=val1, key2=val2, 
    key3=[
            {key4=val4, key5=val5}, 
            {key6=val6, key7=val7} 
        ]
}

我现在想展平该地图,以便所有条目都处于同一级别:

{key1=val1, key2=val2, key4=val4, key5=val5,key6=val6, key7=val7}

当我尝试

map.values().forEach(map.get("key3")::addAll);

described in this post的身份出现以下错误:

invalid method reference
  cannot find symbol
    symbol:   method addAll(T)
    location: class Object
  where T is a type-variable:
    T extends Object declared in interface Iterable

是否有任何通用方法可以平铺给定的Map

3 个答案:

答案 0 :(得分:4)

不确定我是否正确理解了这个问题,但是类似的方法可能有效。 尚未检查所有语法,因此某处可能存在一些错误。

Stream<Map.Entry<String, String>> flatten(Map<String, Object> map) {
  return map.entrySet()
            .stream()
            .flatMap(this::extractValue);         
}

Stream<Map.Entry<String, String>> extractValue(Map.Entry<String, Object> entry) {
   if (entry.getValue() instanceof String) {
      return Stream.of(new AbstractMap.SimpleEntry(entry.getKey(), (String) entry.getValue()));
   } else if (entry.getValue() instanceof Map) {
      return flatten((Map<String, Object>) entry.getValue());
   }
}

那么你可以做:

Map<String, String> flattenedMap = flatten(yourmap)
   .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

答案 1 :(得分:1)

您可以使用递归帮助器方法:

static void forEachValue(Map<String, Object> source, BiConsumer<? super String, ? super Object> action) {
    for (final Map.Entry<String, Object> entry : source.entrySet()) {
        if (entry.getValue() instanceof Map) {
            forEachValue((Map<String, Object>) entry.getValue(), action);
        } else {
            action.accept(entry.getKey(), entry.getValue());
        }
    }
}

然后可以这样称呼它:

Map<String, Object> map = ...;

Map<String, Object> flattened = new HashMap<>();
forEachValue(map, map::put);

我在BiConsumer中使用了这种方法,但并不限于仅将嵌套图展平到另一个图中的方法,但是调用者可以自己决定要对每个键值对做什么。 / p>

答案 2 :(得分:0)

您应该尝试以下操作:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.login_form, null));
builder.setPositiveButton(okText, new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
       View myView = inflater.inflate(R.layout.login_form, (ViewGroup) findViewById(R.id.login_form_root));
       EditText userEmail = (EditText) myView.findViewById(R.id.email_address);
       userEmailValue = userEmail.getText().toString();
       Toast.makeText(getActivity(), userEmailValue, Toast.LENGTH_SHORT).show();
        }

如果您具有多个嵌套级别,则可以使用递归算法。

Map<String, Object> flatenedMap = new HashMap<>();

    map.forEach((key, value) -> {
      if(value instanceof Map) {
        flatenedMap.putAll((Map) value);
      } else {
        flatenedMap.put(key, value);
      }
    });