2015-12-05 71 views
0

Eclipse可以从对象的字段中自动生成toString()方法。如果这些字段是对象,那么它们也可能具有类似的自动生成的toString()方法。从eclipse创建地图地图toString()

例如总统对象可能是这样的:

President [country=USA, name=Name [title=Mr, forename=Barack, surname=Obama], address=Address [houseNumber=1600, street=Pennsylvania Avenue, town=Washington]] 

这是比较容易,如果我格式化阅读:

President [ 
      country=USA, 
      name=Name [ 
         title=Mr, 
         forename=Barack, 
         surname=Obama], 
      address=Address [ 
          houseNumber=1600, 
          street=Pennsylvania Avenue, 
          town=Washington]] 

是什么,解析字符串创建地图的地图的最佳方式?

+0

什么'的toString()'和地图的地图之间的联系? – Tunaki

+0

你想做什么:序列化,反序列化,漂亮打印? –

+3

这个输出并不是真正意义上的解析。你放弃了类型信息(例如'1600'很可能是一个数字),大括号''和'''不会被转义出来,等等。为什么不使用JSON呢? –

回答

0

我有一个解决方案,但它不漂亮。我希望能够避免低水平字符串操作莫名其妙,但here是:

import java.util.LinkedHashMap; 
import java.util.Map; 

public class MappedObject { 

    public String className; 
    public Map<String, String> leafFields = new LinkedHashMap<>(); 
    public Map<String, MappedObject> treeFields = new LinkedHashMap<>(); 

    @Override 
    public String toString() { 
     return "[className=" + className 
       + (leafFields.isEmpty() ? "" : ", leafFields=" + leafFields) 
       + (treeFields.isEmpty() ? "" : ", treeFields=" + treeFields) 
       + "]"; 
    } 

    public static MappedObject createFromString(String s) { 
     MappedObject mo = new MappedObject(); 
     new Mapper(s).mapObject(mo); 
     return mo; 
    } 

    private static class Mapper { 

     private String s; 

     public Mapper(String s) { 
      this.s = s; 
     } 

     private String mapObject(MappedObject mo) { 
      mo.className = removeFirstNCharacters(s.indexOf(' ')); 

      while (s.contains("=")) { 
       removeLeadingNonLetters(); 
       String key = removeFirstNCharacters(s.indexOf('=')); 
       removeFirstNCharacters(1); // remove the = 
       String leafValue = getLeafValue(); 
       if (leafValue != null) { 
        mo.leafFields.put(key, leafValue); 
        if (s.startsWith("]")) { // that was the last field in the tree 
         return s; 
        } 
       } else { 
        MappedObject treeField = new MappedObject(); 
        mo.treeFields.put(key, treeField); 
        s = new Mapper(s).mapObject(treeField); 
       } 
      } 
      return s; // s contains only close brackets - ] 
     } 

     private void removeLeadingNonLetters() { 
      int i = 0; 
      while (!Character.isLetter(s.charAt(i))) { 
       i++; 
      } 
      removeFirstNCharacters(i); 
     } 

     private String removeFirstNCharacters(int n) { 
      String value = s.substring(0, n); 
      s = s.substring(value.length()); 
      return value; 
     } 

     private String getLeafValue() { 
      int endIndex = getEndIndex(); 
      if (!s.contains("[") || s.indexOf('[') > endIndex) { 
       return removeFirstNCharacters(endIndex); 
      } 
      return null; 
     } 

     /** The end of the value, if it's a leaf field. */ 
     private int getEndIndex() { 
      if(s.contains(",")) { 
       return Math.min(s.indexOf(','), s.indexOf(']')); 
      } 
      return s.indexOf(']'); 
     } 
    } 
}