【问题标题】:Convert HashMap.toString() back to HashMap in Java将 HashMap.toString() 转换回 Java 中的 HashMap
【发布时间】:2011-04-26 19:19:47
【问题描述】:

我将键值对放入 Java HashMap 中,并使用 toString() 方法将其转换为 String

是否可以将此String 表示转换回HashMap 对象并使用其对应的键检索值?

谢谢

【问题讨论】:

  • 不好的问题,一般 object->toString() 是单向转换。有时 toString()->object 可以实现,但不是所有类。最好在某些答案中使用 objectOutputStream。

标签: java hashmap


【解决方案1】:

您可以为此使用 Google 的“GSON”开源 Java 库,

示例输入 (Map.toString):{name=Bane, id=20}

要再次插入到 HashMap 中,您可以使用以下代码:

yourMap = new Gson().fromJson(yourString, HashMap.class);

那就是享受。

(在杰克逊图书馆映射器中会产生异常“期望双引号开始字段名”)

【讨论】:

    【解决方案2】:

    使用 ByteStream 可以转换字符串,但如果字符串很大,它可能会遇到 OutOfMemory 异常。 Baeldung 在这里提供了一些不错的解决方案:https://www.baeldung.com/java-map-to-string-conversion

    使用 StringBuilder :

    public String convertWithIteration(Map<Integer, ?> map) {
    StringBuilder mapAsString = new StringBuilder("{");
    for (Integer key : map.keySet()) {
        mapAsString.append(key + "=" + map.get(key) + ", ");
    }
    mapAsString.delete(mapAsString.length()-2, mapAsString.length()).append("}");
    return mapAsString.toString(); }
    

    请注意,lambda 仅适用于 8 级及以上语言 使用流:

    public String convertWithStream(Map<Integer, ?> map) {
    String mapAsString = map.keySet().stream()
      .map(key -> key + "=" + map.get(key))
      .collect(Collectors.joining(", ", "{", "}"));
    return mapAsString; }
    

    使用 Stream 将字符串转换回地图:

    public Map<String, String> convertWithStream(String mapAsString) {
    Map<String, String> map = Arrays.stream(mapAsString.split(","))
      .map(entry -> entry.split("="))
      .collect(Collectors.toMap(entry -> entry[0], entry -> entry[1]));
    return map; }
    

    【讨论】:

      【解决方案3】:

      toString() 方法依赖于toString() 的实现,在大多数情况下它可能是有损的。

      这里不可能有无损解决方案。但更好的方法是使用对象序列化

      将对象序列化为字符串

      private static String serialize(Serializable o) throws IOException {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(baos);
          oos.writeObject(o);
          oos.close();
          return Base64.getEncoder().encodeToString(baos.toByteArray());
      }
      

      将字符串反序列化回对象

      private static Object deserialize(String s) throws IOException,
              ClassNotFoundException {
          byte[] data = Base64.getDecoder().decode(s);
          ObjectInputStream ois = new ObjectInputStream(
                  new ByteArrayInputStream(data));
          Object o = ois.readObject();
          ois.close();
          return o;
      }
      

      这里如果用户对象的字段是瞬态的,它们会在这个过程中丢失。


      旧答案


      一旦你使用 toString() 将 HashMap 转换为字符串;并不是说您可以将其从该字符串转换回 Hashmap,它只是它的字符串表示形式。

      您可以将 HashMap 的引用传递给方法,也可以将其序列化

      这里是 toString() 的描述 toString()
      Here 是带有序列化解释的示例代码。

      并将 hashMap 作为 arg 传递给方法。

      public void sayHello(Map m){
      
      }
      //calling block  
      Map  hm = new HashMap();
      sayHello(hm);
      

      【讨论】:

      • 请您详细解释一下。
      • 这个答案没有意义。
      • @WeareBorg ,感谢您指出,这是我作为初级工程师写的 8 年前的答案。让我重新写一遍
      【解决方案4】:

      这可能是低效且间接的。但是

          String mapString = "someMap.toString()";
          new HashMap<>(net.sf.json.JSONObject.fromObject(mapString));
      

      应该工作!!!

      【讨论】:

        【解决方案5】:

        我希望您实际上需要通过传递 hashmap 键从字符串中获取值。如果是这种情况,那么我们不必将其转换回 Hashmap。使用以下方法,您将能够获取值,就好像它是从 Hashmap 本身检索的一样。

        String string = hash.toString();
        String result = getValueFromStringOfHashMap(string, "my_key");
        
        /**
         * To get a value from string of hashmap by passing key that existed in Hashmap before converting to String.
         * Sample string: {fld_category=Principal category, test=test 1, fld_categoryID=1}
         *
         * @param string
         * @param key
         * @return value
         */
        public static String getValueFromStringOfHashMap(String string, String key) {
        
        
            int start_index = string.indexOf(key) + key.length() + 1;
            int end_index = string.indexOf(",", start_index);
            if (end_index == -1) { // because last key value pair doesn't have trailing comma (,)
                end_index = string.indexOf("}");
            }
            String value = string.substring(start_index, end_index);
        
            return value;
        }
        

        为我做这项工作。

        【讨论】:

          【解决方案6】:

          您不能直接执行此操作,但我以如下疯狂方式执行此操作...

          基本思路是,首先需要将 HashMap String 转换为 Json,然后再使用 Gson/Genson 等将 Json 反序列化为 HashMap。

          @SuppressWarnings("unchecked")
          private HashMap<String, Object> toHashMap(String s) {
              HashMap<String, Object> map = null;
              try {
                  map = new Genson().deserialize(toJson(s), HashMap.class);
              } catch (TransformationException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return map;
          }
          
          private String toJson(String s) {
              s = s.substring(0, s.length()).replace("{", "{\"");
              s = s.substring(0, s.length()).replace("}", "\"}");
              s = s.substring(0, s.length()).replace(", ", "\", \"");
              s = s.substring(0, s.length()).replace("=", "\":\"");
              s = s.substring(0, s.length()).replace("\"[", "[");
              s = s.substring(0, s.length()).replace("]\"", "]");
              s = s.substring(0, s.length()).replace("}\", \"{", "}, {");
              return s;
          }
          

          实施...

          HashMap<String, Object> map = new HashMap<String, Object>();
          map.put("Name", "Suleman");
          map.put("Country", "Pakistan");
          String s = map.toString();
          HashMap<String, Object> newMap = toHashMap(s);
          System.out.println(newMap);
          

          【讨论】:

            【解决方案7】:

            您是否仅限使用 HashMap ??

            为什么不能这么灵活JSONObject 你可以用它做很多事情。

            您可以将String jsonString 转换为JSONObject jsonObj

            JSONObject jsonObj = new JSONObject(jsonString);
            Iterator it = jsonObj.keys();
            
            while(it.hasNext())
            {
                String key = it.next().toString();
                String value = jsonObj.get(key).toString();
            }
            

            【讨论】:

              【解决方案8】:

              如果 toString() 包含恢复对象所需的所有数据,它将起作用。例如,它适用于字符串映射(其中字符串用作键和值):

              // create map
              Map<String, String> map = new HashMap<String, String>();
              // populate the map
              
              // create string representation
              String str = map.toString();
              
              // use properties to restore the map
              Properties props = new Properties();
              props.load(new StringReader(str.substring(1, str.length() - 1).replace(", ", "\n")));       
              Map<String, String> map2 = new HashMap<String, String>();
              for (Map.Entry<Object, Object> e : props.entrySet()) {
                  map2.put((String)e.getKey(), (String)e.getValue());
              }
              

              虽然我真的不明白你为什么需要这个,但这很有效。

              【讨论】:

              • map.put("k=2", "v=2"); System.out.println(map2.get("k=2"));输出为:null
              • @seyed 您需要在将其转换为字符串之前对键和值进行编码(例如 URLencode)并在反转换字符串后进行解码以避免任何语法问题。
              【解决方案9】:

              我将 HashMap 转换为字符串 使用 toString() 方法并传递给 另一种采用字符串的方法 并将此字符串转换为 HashMap 对象

              这是一种非常、非常糟糕的传递 HashMap 的方法。

              理论上它可以工作,但是出错的地方太多了(而且性能会很差)。显然,在您的情况下确实出了问题。没有看到您的代码,我们无法说出什么。

              但更好的解决方案是更改“另一种方法”,使其仅将HashMap 作为参数而不是一个字符串表示形式。

              【讨论】:

              • 我认为他的意思是在不同的实例中调用这些方法。即实例 A 将 Map 序列化为字符串,实例 B 必须将字符串反序列化为 Map 对象。
              【解决方案10】:

              您无法从字符串恢复为对象。所以你需要这样做:

              HashMap<K, V> map = new HashMap<K, V>();
              
              //Write:
              OutputStream os = new FileOutputStream(fileName.ser);
              ObjectOutput oo = new ObjectOutputStream(os);
              oo.writeObject(map);
              oo.close();
              
              //Read:
              InputStream is = new FileInputStream(fileName.ser);
              ObjectInput oi = new ObjectInputStream(is);
              HashMap<K, V> newMap = oi.readObject();
              oi.close();
              

              【讨论】:

                【解决方案11】:

                可以从其字符串表示中重建一个集合,但如果集合的元素不覆盖它们自己的 toString 方法,它将无法工作。

                因此,使用像 XStream 这样的第三方库更安全、更容易,它以人类可读的 XML 流式传输对象。

                【讨论】:

                  【解决方案12】:

                  你尝试了什么?

                  objectOutputStream.writeObject(hashMap);
                  

                  应该可以正常工作,前提是 hashMap 中的所有对象都实现了 Serializable。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2015-01-14
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-02-03
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多