SnakeYAML正在实例化ArrayList而不是HashMap

2024-05-18

我需要解析以下 YAML 文件。

arguments:
  - Database
  - Fold
  - MetaFeature
  - Algorithm
  - Config
processes:
  - id: MetaFeatureCalculator
    command: "python metaFeatCalc.py {Database} folds/{Fold} de/{MetaFeature}/{Algorithm}.csv"
    in: [Database, Fold]
    out: [MetaFeature, Algorithm]
    log: "mf/{Fold}/{MetaFeature}.out"
  - id: Tunner
    command: "java -jar tunner.jar {MetaFeature} alg/{Algorithm} {config}"
    in: [Metafeature, Algorithm]
    out: [Config]
    log: "mf/{Metafeature}/{Algorithm}.out"
recipeDefaults:
  - Database: ["D1"]
recipes:
  - id: Ex1
    uses:
      - Database: ["D1", "D2"]
      - MetaFeature: ["M1", "M2"]
      - Algorithm: ["A1", "A2"]
      - Config: ["C1", "C4"]
  - id: Ex2
    uses:
      - Folds: ["F1", "F2", "F5"]
      - MetaFeature: ["M1", "M2"]
      - Algorithm: ["A1", "A2"]
      - Config: ["C1", "C4"]

我创建了以下 POJO 来接收这些数据。

Repo: https://github.com/Pacheco95/ExperimentLoader https://github.com/Pacheco95/ExperimentLoader

@Data
public class Experiment {
  private HashSet<String> arguments;
  private HashSet<Process> processes;
  private HashSet<HashMap<String, HashSet<String>>> recipeDefaults;
  private HashSet<Recipe> recipes;
}
@Data
public class Process {
  private String id;
  private String command;
  private HashSet<String> in;
  private HashSet<String> out;
  private String log;
}
@Data
public class Recipe {
  private String id;
  private HashSet<HashMap<String, HashSet>> uses;
}

这个类来测试解析器:

public class ExperimentLoader {
  public static void main(String[] args) throws IOException {
    InputStream is = args.length == 0 ? System.in : Files.newInputStream(Paths.get(args[0]));
    Yaml yaml = new Yaml();
    Experiment experiment = yaml.loadAs(is, Experiment.class);
    Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
    System.out.println(gson.toJson(experiment));
  }
}

解析器似乎运行良好,但在调试模式下运行此代码时,某些字段已使用正确的类型(HashSet)实例化,而其他字段则没有。它们被实例化为 ArrayLists(我不知道这里发生了什么样的魔法)。

这是调试窗口的快照:

我的测试类的输出:

{
  "arguments": [
    "Fold",
    "MetaFeature",
    "Config",
    "Database",
    "Algorithm"
  ],
  "processes": [
    {
      "id": "MetaFeatureCalculator",
      "command": "python metaFeatCalc.py {Database} folds/{Fold} de/{MetaFeature}/{Algorithm}.csv",
      "in": [
        "Fold",
        "Database"
      ],
      "out": [
        "MetaFeature",
        "Algorithm"
      ],
      "log": "mf/{Fold}/{MetaFeature}.out"
    },
    {
      "id": "Tunner",
      "command": "java -jar tunner.jar {MetaFeature} alg/{Algorithm} {config}",
      "in": [
        "Metafeature",
        "Algorithm"
      ],
      "out": [
        "Config"
      ],
      "log": "mf/{Metafeature}/{Algorithm}.out"
    }
  ],
  "recipeDefaults": [
    {
      "Database": [
        "D1"
      ]
    }
  ],
  "recipes": [
    {
      "id": "Ex2",
      "uses": [
        {
          "MetaFeature": [
            "M1",
            "M2"
          ]
        },
        {
          "Folds": [
            "F1",
            "F2",
            "F5"
          ]
        },
        {
          "Config": [
            "C1",
            "C4"
          ]
        },
        {
          "Algorithm": [
            "A1",
            "A2"
          ]
        }
      ]
    },
    {
      "id": "Ex1",
      "uses": [
        {
          "MetaFeature": [
            "M1",
            "M2"
          ]
        },
        {
          "Config": [
            "C1",
            "C4"
          ]
        },
        {
          "Database": [
            "D1",
            "D2"
          ]
        },
        {
          "Algorithm": [
            "A1",
            "A2"
          ]
        }
      ]
    }
  ]
}

我的依赖项:

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.24</version>
  </dependency>
  <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
  </dependency>
</dependencies>

有人遇到过这个问题吗?我找不到解决方案。


你的问题可能是类型擦除 https://bitbucket.org/asomov/snakeyaml/wiki/Documentation:

当类型安全(通用)集合是 JavaBean 属性时,SnakeYAML 会动态检测所需的类。 […]

如果泛型类型是抽象类(接口),则它不起作用。您必须在 YAML 中放置显式标记或提供显式 TypeDescription。 TypeDescription 的目标是收集更多信息并在加载/转储时使用它。

虽然您不使用抽象类或接口,但我认为 SnakeYaml 在发现嵌套泛型类型时存在问题HashSet<HashMap<String, HashSet>>。文档建议添加 TypeDescription;但这并不能解决您的问题,因为接口的设计使您只能指定外部内部的类型HashSet,但不在内部HashMap。该接口不需要嵌套容器的事实也暗示这是您的问题。

解决方法是在 YAML 中将显式标记添加到无法正确加载的集合中:

- Database: !!set ["D1"]
- MetaFeature: !!set ["M1", "M2"]

如果您不想这样做,您基本上还有两个其他选择:将此功能修补到 SnakeYAML 中,或者使用低级 API 并从解析器事件手动生成类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SnakeYAML正在实例化ArrayList而不是HashMap 的相关文章

  • 是否可以在 Spring Batch 中结合分区和并行步骤?

    我只是想知道它在 Spring Batch 中可行吗 Step1Step2 流程 gt 流程1 流程2 流程3 Step3 其中每个flow1 gt 划分为 5 个 GridSizeflow2 gt 划分为 5 个 GridSizeflow
  • Google 地图查询返回的 JSON 包含像 \x26 这样的编码字符(如何解码?)

    在 Java 应用程序中 我获取 JSON 来自 Google 地图 其中包含以下字符 x26我想将其转换为其原始字符 据我所知 这是一个 UTF 8 表示法 但我不完全确定 在源 JSON 中 可能会出现各种编码字符 例如 x3c div
  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • java.lang.Class: 在 java 程序中初始化 log4j 属性文件时出错

    我正在尝试使用 log4j 运行独立的 java 程序 但在调试时收到以下消息 控制台上没有 log4j 相关日志 log Logger 1343 java lang Class ERROR in 18b4aac2 有人可以建议这里出了什么
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 使用 Spring 时实例化对象,用于测试与生产

    使用 Spring 时 应该使用 Spring 配置 xml 来实例化生产对象 并在测试时直接实例化对象 这样的理解是否正确 Eg MyMain java package org world hello import org springf
  • Java 重写 hashCode() 得到 StackOverflowError

    所以我不太熟悉重写 hashCode 并且我似乎在 hashCode 方法中以某种方式进行了一些无限递归 这是我的场景 我有一个 DuplicateCache 类 它是一个缓存对象 用于检查系统中的重复对象 我有一个静态内部类 Duplic
  • 方法断点可能会大大减慢调试速度

    每当向方法声明行添加断点 在 Intellij IDEA 或 Android Studio 中 时 都会出现一个弹出窗口 方法断点可能会大大减慢调试速度 为什么会这样戏剧性地减慢调试速度 是我的问题吗 将断点放在函数的第一行有什么不同 Th
  • JavaFX - setVisible 隐藏元素但不重新排列相邻节点

    在 JavaFX 中 如果我有一个场景有 2VBox元素和每个VBox有多个Label in it 如果我设置顶部VBox to 无形的 为什么底部VBox 不向上移动顶部的场景VBox was The VBox is 无形的但我希望其他物
  • Java 变量的作用域

    我不明白为什么这段代码的输出是10 package uno public class A int x 10 A int x 12 new B public static void main String args int x 11 new
  • 服务器到 Firebase HTTP POST 结果为响应消息 200

    使用 Java 代码 向下滚动查看 我使用 FCM 向我的 Android 发送通知消息 当提供正确的服务器密钥令牌时 我收到如下所示的响应消息 之后从 FCM 收到以下响应消息 Response 200 Success Message m
  • 如何将参数传递给 Symfony2 中的验证约束 - 在 yml 中

    我正在尝试向我的应用程序添加一个包范围的参数 以便我可以将其添加到我的验证约束文件 validation yml 中 myApp myBundle Entity Contact properties name NotBlank messag
  • Java:VM 如何在 32 位处理器上处理 64 位“long”

    JVM 如何在 32 位处理器上处理 64 位的原始 long 在多核 32 位机器上可以并行利用多个核心吗 64 位操作在 32 位机器上慢了多少 它可能使用多个核心来运行不同的线程 但不会并行使用它们进行 64 位计算 64 位长基本上
  • 尝试在没有 GatewayIntent 的情况下访问消息内容

    我希望每当我写一条打招呼的消息时 机器人都会在控制台中响应一条消息 但它只是给我一个错误 JDA MainWS ReadThread WARN JDA Attempting to access message content without
  • 参数动态时如何构建 JPQL 查询?

    我想知道是否有一个好的解决方案来构建基于过滤器的 JPQL 查询 我的查询太 富有表现力 我无法使用 Criteria 就像是 query Select from Ent if parameter null query WHERE fiel
  • 从java中的字符串数组中删除空值

    java中如何从字符串数组中删除空值 String firstArray test1 test2 test4 我需要像这样没有 null 空 值的 firstArray String firstArray test1 test2 test4
  • Path2D 上的鼠标指针检测

    我构建了一个Path2D http docs oracle com javase 7 docs api java awt geom Path2D html表示由直线组成的未闭合形状 我希望能够检测何时单击鼠标并且鼠标指针靠近路径 在几个像素
  • 重写Object类的finalize()方法有什么用?

    据我所知 在java中如果我们想手动调用垃圾收集器 我们可以执行System gc 1 我们在重写的finalize 方法中做了哪些操作 2 如果我们想手动调用JVM垃圾收集器 是否需要重写finalize 方法 我们在重写的 Finali
  • Java中获取集合的幂集

    的幂集为 1 2 3 is 2 3 2 3 1 2 1 3 1 2 3 1 假设我有一个Set在爪哇中 Set
  • Java 推断泛型类型

    我正在寻找类似的推断捕获泛型类型的概念 类似于以下方法片段 但不是捕获泛型类型的类 public

随机推荐