Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 取消设置值的哈希映射_Java - Fatal编程技术网

Java 取消设置值的哈希映射

Java 取消设置值的哈希映射,java,Java,我目前有一个键值对的映射,格式为 a.b.c: value1 e.f: value2 g: [ g.h: nested_value1 g.i: nested_value2 ] 我需要在嵌套结构中将其“展开”到一个新的映射- a: b: c: value1 e: f: value2 g: [ h: nested_value1 i: nested_value2 ] 我当前的尝试没有走多远,抛出了ConcurrentModificationException pri

我目前有一个键值对的映射,格式为

a.b.c: value1
e.f: value2
g: [
  g.h: nested_value1
  g.i: nested_value2
]
我需要在嵌套结构中将其“展开”到一个新的映射-

a:
  b:
    c: value1
e:
  f: value2
g: [
  h: nested_value1
  i: nested_value2
]
我当前的尝试没有走多远,抛出了ConcurrentModificationException

private static Map<String, Object> unflatten(Map<String, Object> flattened) {
    Map<String, Object> unflattened = new HashMap<>();
    for (String key : flattened.keySet()) {
        doUnflatten(flattened, unflattened, key, flattened.get(key));
    }
    return unflattened;
}

private static Map<String, Object> doUnflatten(
    Map<String, Object> flattened,
    Map<String, Object> unflattened,
    String key,
    Object value) {

    String[] parts = StringUtils.split(key, '.');
    for (int i = 0; i < parts.length; i++) {
        String part = parts[i];
        Object current = flattened.get(part);
        if (i == (parts.length - 1)) {
            unflattened.put(part, value);
        } else if (current == null) {
            if ((current = unflattened.get(part)) == null) {
                current = new HashMap<>();
            }
            unflattened.put(part, current);
            unflattened = (Map<String, Object>) current;
        } else if (current instanceof Map) {
            unflattened.put(part, current);
            unflattened = (Map<String, Object>) current;
        }
    }
    return unflattened;
}
private静态映射展开(映射展开){
Map unflatteed=新的HashMap();
for(字符串键:展平.keySet()){
doUnflatten(展平,未展平,键,展平,get(键));
}
不加宣传地返回;
}
私有静态映射doUnflatten(
地图变平,
地图没有平台,
字符串键,
对象值){
String[]parts=StringUtils.split(键“.”);
对于(int i=0;i
我是不是漏掉了什么明显的东西?一种解决方案是使用JSONFlatter这样的库——唯一的问题是这将涉及在JSON之间来回转换


编辑:谢谢你的指点——我已经说到一半了,有一件事我忘了提一下,那就是它还需要取消一组HashMaps的框架

你的错误是因为你迭代了密钥集,然后更改了映射,而不是通过迭代器

该类的所有“集合”视图返回的迭代器 方法“是快速失效的:如果地图在任何时候被结构修改 创建迭代器后的时间,以任何方式,除了通过 迭代器自己的remove方法,迭代器将抛出 ConcurrentModificationException。因此,面对同时发生的冲突, 修改后,迭代器会快速、干净地失败,而不是 在不确定的时间冒任意、不确定行为的风险 将来


您可以通过使用新地图来解决此问题。

最简单的解决方案是替换线条

for (String key : flattened.keySet()) {

for(字符串键:新的ArrayList(flatted.keySet())){

但是,对于大数据量,从性能角度来看,它可能不是非常有效。

实现的问题是,您正在将输出写入用于输入的同一个
Map
,这会导致
ConcurrentModificationException

通过单独的
映射
输出,实现变得简单:

Map<String,Object> unflattened = new HashMap<>();
for (Map.Entry<String,Object> e : flattened.entrySet()) {
    String[] parts = StringUtils.split(e.getKey(), ".");
    // Find the map to be used as a destination for put(...)
    Map<String,Object> dest = unflattened;
    for (int i = 0 ; i != parts.length-1 ; i++) {
        Object tmp = dest.get(parts[i]);
        if (tmp == null) {
            // We did not see this branch yet
            Map<String,Object> next = new HashMap<>();
            dest.put(parts[i], next);
            dest = next;
            continue;
        }
        if (!(temp instanceof Map)) {
            throw new IllegalStateException();
        }
        dest = (Map<String,Object>)temp;
    }
    // Put the entry into the destination Map<>
    dest.put(parts[parts.length-1], e.getValue());
}

为您的结果创建一个新的
Map
实例,而不是尝试重用当前实例。另外,请发送Map值,这样就不需要提取:

private static Map<String, Object> unflatten(Map<String, Object> flattened) {
    Map<String, Object> unflattened = new HashMap<>();
    for (String key : flattened.keySet()) {
        doUnflatten(unflattened, key, flattened.get(key));
    }
    return unflattened;
}

注意事项:无需从方法返回映射。将循环分为两种不同的情况:要么将值写入映射,要么创建或检索嵌套映射。

好的,您正在修改迭代的同一对象。也许您应该尝试为每个键创建一个新的hashmap,并将其附加到另一个new hashmap。不需要修改作为参数传递的映射,您可以更改函数来构建并返回一个“未设置”的新映射。是的,刚刚注意到我自己会覆盖值-需要检查该叶是否已经在新映射中!
"a.b.c" -> "x" // OK: "a.b" is a branch
"a.b.d" -> "y" // OK: "a.b" is a branch
"a.b"   -> "z" // Error: "a.b" is a leaf
private static Map<String, Object> unflatten(Map<String, Object> flattened) {
    Map<String, Object> unflattened = new HashMap<>();
    for (String key : flattened.keySet()) {
        doUnflatten(unflattened, key, flattened.get(key));
    }
    return unflattened;
}
private static void doUnflatten(Map<String, Object> current, String key,
  Object originalValue) {
    String[] parts = StringUtils.split(key, ".");
    for (int i = 0; i < parts.length; i++) {
        String part = parts[i];
        if (i == (parts.length - 1)) {
            current.put(part, originalValue);
            return;
        }

        Map<String, Object> nestedMap = (Map<String, Object>) current.get(part);
        if (nestedMap == null) {
            nestedMap = new HashMap<>();
            current.put(part, nestedMap);
        }

        current = nestedMap;
    }
}