【问题标题】:Output error while creating Java Json array object with List and Hashmap使用 List 和 Hashmap 创建 Java Json 数组对象时输出错误
【发布时间】:2016-07-09 08:06:45
【问题描述】:

我想用 List 和 hashmap 创建一个 Json 数组对象,但是在程序执行过程中遇到了一些奇怪的问题。

这是我的代码:

List<HashMap> list = new ArrayList<>();
HashMap<String, String> hmap = new HashMap<>();
String raw = "<CONTENT><DETAIL><USER>user1</USER><MAIL>abc@test.com</MAIL></DETAIL><DETAIL><USER>user2</USER><MAIL>def@test.com</MAIL></DETAIL></CONTENT>";
String partRas = "";
int index = raw.indexof("<USER>");

while(index >= 0) {
    if(index + 50 < raw.length())
        partRaw = raw.subString(index, index + 50);

    hmap("user", getTagValue(partRaw, "USER"));
    hmap("email", getTagValue(partRaw, "MAIL"));
    list.add(hmap);

    raw = raw.subString(index + 50, raw.length());
    index = raw.indexof("<USER>");
}

System.out.println(new Gson().toJson(list));


public static String getTagValue(String xml, String tagName){
    return xml.split("<"+tagName+">")[1].split("</"+tagName+">")[0];
}

这段代码看起来合法,但是当我执行这段代码时,我预计会得到这样的结果:

[{"user":"user1","email":"abc@test.com"},{"user":"user2","email":"def@test.com"}]

但我得到的是这样的:

[{"user":"user2","email":"def@test.com"},{"user":"user2","email":"def@test.com"}]

我能想到的这个问题的唯一答案是“它是通过地址传递”,所以我推入列表的第一个结果受到第二次迭代的影响。

我想问的问题:有谁知道得到我想要的结果的方法吗?

我不希望答案告诉我在一开始就定义多个 HashMap,因为我的原始数据可能包含更多“”,这意味着它可以包含尽可能多的“USER”和“MAIL”数据。

【问题讨论】:

  • 此代码不是minimal reproducible example。特别是它没有显示map 的定义位置。如果我要猜,那是你的问题。每次开始解析新用户条目时,您都不会创建 map 的新实例 - 因此旧条目中的值只会不断被覆盖。 (hmap 应该是map 吧?)。
  • 打字错误,现已更正。
  • @Tibrogargan 这是否意味着我必须在 while 循环内的每次迭代中动态定义新的 HashMap?
  • 我会做一个答案,更容易告诉你

标签: java json hashmap


【解决方案1】:

hmap 在您的代码中被重用,值被覆盖,因此当您将其添加到列表中时,您只是添加了对同一事物的新引用。

List<HashMap> list = new ArrayList<>();
HashMap<String, String> hmap;
String raw = "<CONTENT><DETAIL><USER>user1</USER><MAIL>abc@test.com</MAIL></DETAIL><DETAIL><USER>user2</USER><MAIL>def@test.com</MAIL></DETAIL></CONTENT>";
String partRas = "";
int index = raw.indexof("<USER>");

while(index >= 0) {
    if(index + 50 < raw.length())
        partRaw = raw.subString(index, index + 50);

    /*
     * Create a new, empty HashMap 
     */
    hmap = new HashMap<>();
    hmap("user", getTagValue(partRaw, "USER"));
    hmap("email", getTagValue(partRaw, "MAIL"));
    list.add(hmap);

    raw = raw.subString(index + 50, raw.length());
    index = raw.indexof("<USER>");
}

System.out.println(new Gson().toJson(list));

public static String getTagValue(String xml, String tagName){
    return xml.split("<"+tagName+">")[1].split("</"+tagName+">")[0];
}

你可能真的想检查一下(即使错误检查很糟糕):

String raw = "<CONTENT><DETAIL><USER>user1</USER><MAIL>abc@test.com</MAIL></DETAIL><DETAIL><USER>user2</USER><MAIL>def@test.com</MAIL></DETAIL></CONTENT>";
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;

try {
    dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(new ByteArrayInputStream(raw.getBytes()));
    NodeList nodes = doc.getElementsByTagName("DETAIL");
    for (int idx = 0; idx < nodes.getLength(); idx++) {
        Node node = nodes.item(idx);
        System.out.println("User: "+((Element)node).getElementsByTagName("USER").item(0).getTextContent());
        System.out.println("Mail: "+((Element)node).getElementsByTagName("MAIL").item(0).getTextContent());
    }
} catch (Exception ex) {
    // do stuff
}

【讨论】:

  • 嗯,看来我别无选择,只能使用动态定义。我以为List的add()函数是传值的,但是在这个bug之后我觉得我错了。
  • @Kaninchen java 不按值传递,除了原始类型。
  • 以前学过太多指针的东西,所以这个错误让我很困惑,因为我在 oracle 文档的函数参数字段中没有看到 *&amp;。这就是为什么我认为它之前是按值传递的。
猜你喜欢
  • 2019-05-03
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 2016-01-07
相关资源
最近更新 更多