2012-08-29 38 views
1

我得到這樣的名單,每行一個對象持普通字符串:轉化名單多重嵌套地圖

Vehicle, Name, Property, Value 
------------------------------ 
Car, VW, Tires, 4 
Car, VW, Doors, 4 
Car, Porsche, Tires, 4 
Car, Porsche, Doors, 2 
Car, Porsche, Color, Red 
Plane, A340, Tires, 12 
Plane, A340, Color, White 
Plane, A750, Doors, 6 
Forklift, ABC345, Color, Orange 
... and so on 

我想回到作爲JSON的形式:

{ 
"Car" : { 
    "VW":{ "Tires" : "4", "Doors": "4"}, 
    "Porsche":{ "Tires" : "4", "Doors": "2" } 
    }, 
"Plane":{ 
    "A340":{ "Tires" : "12", "Color" : "White" }, 
    "A750":{ "Doors" : "6" } 
    }, 
"Forklift" : { 
    "ABC345": { "Color" : "Orange" } 
    } 
} 

我嘗試使用一個奇怪的

HashMap<String, HashMap<String, HashMap<String, String>>> 

但說實話,我不知道如何正確設置它。當我遍歷列表,並寫入到HashMap中,屬性和值會被覆蓋,所以我的結果是這樣的:

{ 
"Car" : { 
    "Porsche":{ "Tires" : "4" } 
    }, 
"Plane":{ 
    "A750":{ "Doors" : "6" } 
    }, 
"Forklift" : { 
    "ABC345": { "Color" : "Orange" } 
    } 
} 

我是相當新的Java和不知道這是怎麼樣的手柄嵌套地圖。

我的意思是,要求被寵愛是有點尷尬,但也許有人可以告訴我如何以正確的方式做到這一點。

編輯:在這裏,我如何添加值,我沒有粘貼這部分代碼,因爲我不知道如何檢查和決定怎麼做。

HashMap<String, HashMap<String, HashMap<String, String>>> vehiclesData = new HashMap<String, HashMap<String, HashMap<String, String>>>(); 

for(VehicleReportRow vehicleReportRow : unpreparedRows){ 
    String vehicle = vehicleReportRow.getVehicle(); 
    String name = vehicleReportRow.getName(); 
    String property = vehicleReportRow.getProperty(); 
    String value = vehicleReportRow.getValue(); 

    //the most inner dataset 
    HashMap<String,String> propAndVal = new HashMap<String, String>(); 
    propAndVal.put(property, value); 

    //the middle dataset    
    HashMap<String, HashMap<String,String>> nameToProps = new HashMap<String, HashMap<String,String>>(); 
    nameToProps.put(name, propAndVal); 

    //and finally the outer dataset 
    vehiclesData.put(vehicle, nameToProps); 
} 
+0

如何擁有一個'List '其中'Vehicle'包含'List '而'Model'具有屬性的'Map '。 –

+1

此外,您應該使用您用來填充地圖的代碼更新此問題,以便人們可以提出問題的出現位置。儘管如此,很可能您需要添加檢查項以確定鍵是否已經存在,以便您添加到現有地圖而不是爲結構的前兩層創建新地圖。 – mikej

+0

@Tichodroma爲了公平地回答他提出的其他問題(只有四個問題),不要給出非常詳細的答案。 – NominSim

回答

1

現在看到您的代碼,問題就像我在我的評論中暗示的那樣。例如您每次創建一個新的nameToProps和一個新的propAndVal循環,而不是檢查是否存在應該添加的現有對象。你想要一些支票,如:

for(VehicleReportRow vehicleReportRow : unpreparedRows){ 
    String vehicle = vehicleReportRow.getVehicle(); 
    String name = vehicleReportRow.getName(); 
    String property = vehicleReportRow.getProperty(); 
    String value = vehicleReportRow.getValue(); 

    // check if we have an outermost entry for this vehicle type and if not then 
    // create one and store it in vehiclesData so that next time we can get the same 
    // map for this vehicle type 
    HashMap<String, HashMap<String,String>> nameToProps = vehiclesData.get(vehicle);; 
    if (nameToProps == null) { 
     nameToProps = new HashMap<String, HashMap<String,String>>(); 
     vehiclesData.put(vehicle, nameToProps); 
    } 

    // similarly, check if we already have a props to values map for this name 
    // and create and store one if not 
    HashMap<String,String> propAndVal = nameToProps.get(name); 
    if (propAndVal == null) { 
     propAndVal = new HashMap<String, String>(); 
     nameToProps.put(name, propAndVal); 
    } 

    // store the property and value 
    propAndVal.put(property, value); 
} 

如果任何這需要進一步解釋,請讓我知道。

+0

好的,還有一個問題:如果我得到的列表完全無序,這也可以工作嗎? – ximarin

+0

是的,排序無關緊要。例如如果'Car,VW,Doors,4'行列在列表後面,而不是緊接在'Car,VW,Tires,4'行之後,那麼當我們遇到第一行時,將爲VW創建'propAndVal'而其他屬性將被放入正確的地圖中,而不管它們發生在哪裏。 – mikej

+0

好的,明白了,再次感謝! – ximarin

1

您正在使用兩個較深的散列圖,而您的數據結構深三層。這就像入侵:「我們需要更深入!」

{ 
1: "Car" : { 
2:  "VW":{ 
3:   "Tires" : "4", "Doors": "4" 
     }, 
     "Porsche":{ 
      "Tires" : "4", "Doors": "2" 
     } 
    }, 
}