【问题标题】:Is there a way, I can empty the whole JSONObject -- java有没有办法,我可以清空整个 JSONObject - java
【发布时间】:2015-09-23 05:54:18
【问题描述】:

我必须像这样填充一个 json 对象,假设它被命名为 detailJSON:

{"amount": "5.00", "ac_no": "123456" } 

我是这样做的:

detailJSON.put("amount","5.00");
detailJSON.put("ac_no","123456");

在此之后,在一些共享首选项中输入了详细信息,现在我想清除这个 JSONObject 并使用相同的 detailJSON 对象来存储另一个 json(具有不同的键),这样:

{"amount":"6.00", "loan_no":"123456"}

我知道有一个方法,remove(),可以删除特定的键和对应的值。

这行得通

detailJSON.remove("amount");
detailJSON.remove("ac_no");

然后使用它--

detailJSON.put("amount","6.0");
detailJSON.put("loan_no","123456");

现在这是一个非常简单的例子。在我正在处理的代码中,我有很多键,因此使用 remove 实际上会增加 LOC。此外,每次删除之前,我都需要检查 JSONObject has 是否是那个特定的键。

有没有其他方法,我可以实现 JSONObject 的清除?

我试过了

detailJSON=null ;
detailJSON=new JSONObject();

但它不起作用。

我基本上是在寻找类似 clear() 方法的东西,如果存在的话。

【问题讨论】:

  • 您确定需要这样做吗?为什么不每次都使用新的 JSONObject?我认为删除每个字段比创建一个新字段成本更高。
  • @UweAllner 我也完全同意你的观点,但这是业务限制,要维持这样的结构。
  • detailJSON=new JSONObject(); 应该可以工作。您的代码中似乎存在错误。
  • detailJSON=null; 必须删除对实际对象的引用 detailJSON=new JSONObject(); 必须指向新创建的对象。在创建新对象后,填充新值并检查这是否有效。
  • 好的,这应该有效,但事情是这样的。我将 detailJSON 传递给完成这项工作的函数,所以在这里如果我创建新的 json 对象,它是局部变量,因此它不起作用。而删除对原始参考的工作。

标签: java json


【解决方案1】:
Iterator keys = detailJSON.keys();
while(keys.hasNext())
  detailJSON.remove((String)detailJSON.keys().next());

【讨论】:

  • 这导致编译错误 -- 在 detailJSON.keys() 行中出现 Can only iterate over an array or an instance of java.lang.Iterable。 detailJSON 是 JSONObject 的一个实例。
  • 在你编辑之后,这行得通,但我不得不转换为 String -- detailJSON.remove((String)detailJSON.keys().next());
  • 但它与detailJSON.remove("amount"); 基本相同,更糟糕的是,它会在每个循环中创建两次Iterator。首先确定是否还有其他元素,然后再获取下一个元素。
  • 这将抛出 ConcurrentModificationException
【解决方案2】:

这个版本因为每次都获取key-set有开销,但是没有并发修改异常的情况下工作。

while(json.length()>0)
   json.remove(json.keys().next());

【讨论】:

    【解决方案3】:

    你可以,但这将是一个 hack。

    Iterator i = detailJSON.keys();
    while(i.hasNext()) {
        i.next().remove();
    }
    
    //or
    
    detailJSON.keySet().clear();
    

    它有效,因为JSONObject.keySet() 将返回您this.map.keySet()。以及 HashMap.keySet() 的 JavaDoc 所说的:

    返回此映射中包含的键的 Set 视图。集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。

    集合中的 Java 的 HashMap 将返回 java.util.HashMap.KeySetjava.util.HashMap.KeySet.clear(); 只需调用 map.clear()(KeySet 是 java.util.HashMap 的内部类)

    【讨论】:

    • detailJSON.keySet().clear(); 不起作用,它给出了这个编译错误 -- `The method keySet() is undefined for type JSONObject`。现在尝试第一个解决方案
    • 第一个也给出了一个错误,将类型转换添加到迭代器,这样做,它给出了运行时错误。
    • 您使用哪个 JSONObject。我已经用 sn-p pastebin.com/SBDR3iaB 测试了这种方法
    • 这是我用过的org.json.JSONObject.keySet()grepcode.com/file/repo1.maven.org/maven2/org.json/json/20141113/…
    【解决方案4】:

    你可以用这个方法

    public HashMap clearMap(HashMap detailJSON){
      for(String key: detailJSON.keySet())
        detailJSON.remove(key);
      return detailJSON;
    }
    

    【讨论】:

      【解决方案5】:

      如果detailJSON是一个map变量,你可以使用detailJSON.clear()方法来清空map中的值。

      【讨论】:

      • 它是 JSONObject 变量。
      • 然后 detailJSON = new JSONObject() 应该删除您以前的所有数据,并为您放置和清空 detailJSON 对象
      • 如果detailJSON 被声明为finaldetailJSON = new JSONObject() 将不起作用,因此该注释仅指特定用例。
      【解决方案6】:

      JSONObject 似乎没有明确的方法:。如果您必须遍历所有JSONObject 来清除它,最好获得父节点,并使用new JSONObject() 进行更新。

      您可能使用while 来获取这些详细信息,因此您可以这样做:

      Iterator keys = mJson.keys();
      while(keys.hasNext())
      {
          String key = keys.next();
          JSONObject detailJSON = mJson.getJSONObject(key);
          JSONObject newDetail = new JSONObject();
          ...
          mJson.put(key,newDetail);
      }
      

      而当使用JSONArray:

      for (int i=0; i < mJson.length(); i++)
      {
          JSONObject detailJSON = mJson.getJSONObject(i);
          JSONObject newDetail = new JSONObject();
          ...
          mJson.put(i,newDetail);
      }
      

      【讨论】:

        【解决方案7】:

        将 JSON 设为字符串并打印。 喜欢:

        JSONObject jo =new JSONObject();
        System.out.println(jo.toString());  ```
        

        【讨论】:

          【解决方案8】:

          ConcurrentModificationException 证明?

          在循环中直接使用 JSONObject 的键集迭代器来删除项目将导致抛出 ConcurrentModificationException

          这是因为当您删除一个元素时,JSONObject 会自动修改您当前在循环中使用的它的键集。这是违规行为!

          一种解决方案是先将键复制到数组中,然后使用数组而不是迭代器本身,如下所示:

          public static void clearJson(JSONObject json) {
              if (json.length() > 0) {
                  String[] keysArr = new String[json.length()];
          
                  int counter = 0;
                  for (Iterator<String> iter = json.keys();iter.hasNext();)
                      keysArr[counter++] = iter.next();
          
                  for (String key : keysArr)
                      json.remove(key);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2020-09-09
            • 1970-01-01
            • 2021-12-13
            • 1970-01-01
            • 2011-08-11
            • 1970-01-01
            • 1970-01-01
            • 2020-12-24
            • 2016-01-06
            相关资源
            最近更新 更多