繁体   English   中英

PHP Json关联数组到Java映射

[英]Php Json Associative Array To Java Map

我的问题是,PHP根据数组是连续的还是以零索引开头的方式对数组进行不同的编码。 例:

$arr = array(array(12), array(13));
===> [[12], [13]]

$arr = array("0" => array(12), "1" => array(13));
===> [[12], [13]]

$arr = array("0" => array(12), "2" => array(13));
===> {"0": [12], "2": [13]}

为什么第三个是如此不同?

第一个示例产生一个列表列表,第三个示例产生一个带有列表的对象。 我需要将所有这些都转换为Java的Map<Integer, List<Double>> 这是我可以在Java中为这些PHP对象找到的最通用的数据类型。 我正在使用Google的Gson。 但是,由于这些示例生成了不同类型的对象,因此我不能仅将其读入地图。 我必须首先检查它是否具有索引,然后将其一个接一个地添加到自定义地图中。 请查看标有“做这部分的更好方法”的行。 这是我的代码:

import java.lang.StringBuilder;
import com.google.gson.*;
import com.google.gson.reflect.*;
import java.util.Map;
import java.util.HashMap;
import java.util.List;

public class Saving {

    public static void main(String[] args) {

        String json = "[[12], [13]]";
        json = json.trim();
        Map<Integer, List<Double>> fuelSavings = null;

        // such a cluster****
        if(json.startsWith("[[")) { // THERE HAS TO BE A BETTER WAY TO DO THIS PART
        // ANY WAY I CAN AVOID THIS ENTIRE IF CONDITION

            //implicit keys
            fuelSavings = new HashMap<Integer, List<Double>>();
            List<List<Double>> temporaryList = new Gson().fromJson(json, new TypeToken<List<List<Double>>>(){}.getType());
            int index = 0;
            for(List<Double> temporaryListMember: temporaryList) {
                fuelSavings.put(index, temporaryListMember);
                index++;
            }

        } else {

            // explicit keys
            // THIS PART IS PERFECT
            fuelSavings = new Gson().fromJson(json, new TypeToken<Map<Integer, List<Double>>>(){}.getType());

        }

        System.out.println(fuelSavings);

    }

}

任何帮助表示赞赏,谢谢!

您在PHP中所做的是两件事。 PHP中的数组用作数组,地图,列表。

array(array(12), array(13)); array("0" => array(12), "2" => array(13)); 即使在PHP中也不一样。

使用Gson在Java中需要做的是将json解析为String,并检查主要对象是Map还是List ,然后提出建议。 如果已加载列表,则知道它是一个array(array(12), array(13)); 否则就是另一个。

您不能从PHP方面做一些事情来生成始终相同的东西吗?

编辑:

如果您不能从PHP方面做任何事情,那么您的检查将与实例化JsonParser解析相同,然后检查JsonObject.isJsonArray()返回true,不同之处在于它最终会更快,但您将不必依赖gson库。

Map<Integer, List<Double>> fuelSavings = null;
JsonElement jElement = new JsonParser().parse("[[12], [13]]");
JsonObject jObject = jelement.getAsJsonObject();
if (jObject.isJsonArray()) {
    fuelSavings = new HashMap<Integer, List<Double>>();
    List<List<Double>> temporaryList = new Gson().fromJson(jElement, new TypeToken<List<List<Double>>>(){}.getType());
    int index = 0;
    for(List<Double> temporaryListMember: temporaryList) {
        fuelSavings.put(index++, temporaryListMember);
    }
} else /* this is a map */ {
    fuelSavings = new Gson().fromJson(jElement, new TypeToken<Map<Integer, List<Double>>>(){}.getType());
}

很有意思!

据我了解,PHP服务器将其数据作为编码为JSON的有序映射提供服务,但不幸的是,有时它的键是连续的整数,这使得json_encode()理解为简单数组,并为输出的JSON使用不同的格式。

据我了解,所有PHP数组都是有序映射。 但是,当一个数组具有连续的整数键时, json_encode()在“ JSON Object”(映射)中插入一个没有键的数组。 这破坏了不希望使用数组而不是“对象”的客户代码。

令人难以置信的是,我发现现有的Java函数都无法将JsonArray转换为JsonObject ,而且如果我们尝试将数组作为Object进行获取,有时甚至可能会遇到一些异常! 天哪,一个JsonArray只是一个具有隐式连续整数键的JsonObject ,应该自动JsonArray :p

我没有尝试过,但是也许JsonObject::entrySet()可以解决它。 它返回一个Set<Map.Entry<String,JsonElement>> ,这也许可以被转换为一个Map<Integer, AnyObject>如果整数自动解析字符串和JsonElement可以用一个适当的转换TypeToken

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM