【问题标题】:Php Json Associative Array To Java MapPHP Json 关联数组到 Java 映射
【发布时间】:2012-09-11 19:07:55
【问题描述】:

我的问题是,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 对象找到的最通用的数据类型。我正在使用谷歌的 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);

    }

}

感谢任何帮助,谢谢!

【问题讨论】:

    标签: java php json gson


    【解决方案1】:

    您在 PHP 中所做的事情是两件不同的事情。 PHP 中的数组用作数组、映射、列表。

    array(array(12), array(13));array("0" =&gt; array(12), "2" =&gt; array(13)); 即使在 PHP 中也不相同。

    在 Java 中使用 Gson 需要做的是将 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());
    }
    

    【讨论】:

    • 我知道它们不一样(我正在查看它们产生的不同 json,即使它们具有相同的结构)。 $arr = array("0" =&gt; array(12));$arr = array(array(12)); 是一回事。问题是,如果它们不是连续的并且不以零开头,那么它就不再只是列表的列表。 PHP 不允许我为任何数组生成相同的东西,这是可悲的部分。
    • 查看我对 JSonParser 的编辑,以检查是否使用库而不是 String.startsWith
    • 我希望避免整个 if 条件,而不必从列表列表中手动制作地图。但这是一个选择。谢谢。
    • 这是不可能的,因为你必须处理两种不同的类型,Map 和 List 没有共同的接口,但你已经知道了。如果你不能在 php 端确保所有数组都在 Json 中生成为 Maps,那么你将不得不在 Java 端进行此检查。
    • @除非你比我更了解 PHP,我希望你这样做,否则我们只使用 json_encode,它没有可以更改类型的位掩码。
    【解决方案2】:

    非常有趣!

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

    据我了解,所有 PHP 数组都是有序映射。但是当一个数组有连续的整数键时,json_encode() 会生成一个没有键的数组,而不是一个“JSON 对象”(映射)。这会破坏不期望数组而不是“对象”的客户端代码。

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

    我没有尝试过,但也许JsonObject::entrySet() 可以解决它。它返回一个Set&lt;Map.Entry&lt;String,JsonElement&gt;&gt;,如果Integer 自动解析String 并且JsonElement 可以转换为适当的TypeToken,它可能会转换为Map&lt;Integer, AnyObject&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 2017-02-16
      • 2011-03-05
      • 1970-01-01
      • 2020-07-23
      相关资源
      最近更新 更多