java - 避免在 Java 中未经检查的嵌套映射转换

标签 java generics nested-generics

我有一个 Java 数据结构,它是反序列化这个 JSON 的结果:

{
  'level1 value1': {
    'level2 value1': {
      'level3 value1': [ "25", "45", "78" ],
      // ...
      'level3 valueN': [ "59", "17", "42" ]
    },
    // ...
    'level2 valueN': {
      'level3 value1': [ "34", "89", "54" ],
      // ...
      'level3 valueN': [ "45", "23", "23" ]
    },
  },
  // ...
  'level1 valueN': {
    // ...
  }
}

在 Java 中,这变成:

Map<String, Map<String, Map<String, List<String>>>> data;

当然,层数是任意的,所以我不能真的在变量声明中嵌套集合。我正在做的是:

void traverse(Map<String, ?> children) {
  for (Map.Entry<String, ?> node : data.entrySet()) {
    if (node.getValue() instanceof Map) {
      doSomethingWithNonLeafNode((Map<String, Map<String, ?>>) node);
    } else if (node.getValue() instanceof List) {
      doSomethingWithLeafNode((Map <String, List<String>>) node);
    }
  }
}


void doSomethingWithNonLeafNode(Map <String, Map<String ?>> node) {
  // do stuff
}


void doSomethingWithLeafNode(Map <String, List<String>> node) {
  // do stuff
}

这显然 a) 使用了一些未经检查的转换,b) 很丑陋。我试图定义新类型来解决这个问题:

private interface Node extends Map<String, Map<String, ?>> {
}

private interface LeafNode extends Map<String, List<String>> {
}

// ...

    if (node.getValue() instanceof Map) {
      doSomethingWithNonLeafNode((Node) node);
    } else if (node.getValue() instanceof List) {
      doSomethingWithLeafNode((LeafNode) node);
    }

但是,这给了我一个运行时异常:

java.lang.ClassCastException: java.util.HashMap cannot be cast to com.foo.ReportDataProcessor$Node

我怎样才能以干净、无警告的方式执行此操作?

最佳答案

定义新类型对您没有帮助,因为 JSON 反序列化器不知道您的 Node 和 LeafNode 接口(interface),因此生成的具体集合对象无法实现它们。

由于您事先实际上并不知道 map 的元素类型,因此没有强制执行的编译时类型安全:您只能依赖运行时类型检查。因此,泛型只会让你的生活复杂化,让你的代码更难看,但不会给你带来任何好处。

所以我认为这里最不糟糕的解决方案是放弃泛型,在代码中使用非泛型 MapList 类型。

关于java - 避免在 Java 中未经检查的嵌套映射转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9699641/

相关文章:

java - 如何为 JBoss 实例设置代理

java - Android:如何在显示软键盘的同时显示 Activity 的上下文菜单

java - 预期异常时避免空 catch block

java - 为什么这个 Java 代码不起作用?!通用堆栈

java - 测试两个 Java 对象是否可以相互比较

java - 为什么我不能分配给这个通用变量?

Java 泛型 : assignment with nested wildcard parameters

java - 如何在 Eclipse 中组织导入而不是*更改*星号导入

c# - 检查泛型集合中更多派生类型的正确方法是什么?

带有循环元数据的 Swift 3.1 嵌套泛型错误