2012-06-01 40 views
9

我遇到了很多人似乎面臨來自PHP的相同問題,缺乏體面和易用的關聯數組解決方案。 我讀過這裏的基本上所有建議使用HashMap,像這樣問:Java associative-array關聯數組和Java

但是,我不認爲上述解決方案將解決我的問題。我會解釋。

我有一個包含250個項目(國家)的列表,我想要存儲數據。數據的長度是未定義的,這意味着它可以爲每個「列」保留多個條目,有時不會輸入,有時候是4個等等。

在PHP我可以做到這一點:

$country_data = new array(); 
$country_data["nl"]["currency"] = "euro"; 
$country_data["nl"]["languages"] = "Dutch"; 
... 
$country_data["us"]["currency"] = "US dollar"; 
$country_data["us"]["languages"] = array("English", "Spanish"); 

所以有時候我想存儲陣列,有時沒有。當然,它也可以是隻有一個入口而不是字符串的數組,但我只是說。

所以,問題是,如何在HashMap中存儲和讀取數組中的數組?我知道我很困難的HashMap解決方案,但我仍然不明白這將如何讓我存儲數組,我敢肯定,我忽略了一些簡單的東西。基於我的例子會很棒!

UPDATE

我選擇去HashMaps這樣 這樣做的原因,我需要能夠很容易地監督一切,並在需要時更改值的幾行包含HashMap。這很靈活,我可以很容易地根據國家代碼或語言獲取國家/地區名稱,或者我可以在需要時獲得country_data HashMap或所有國家/地區名稱等等。

public class iso_countries { 
    Map<String, Object> country_data  = new HashMap<String, Object>(); 
    Map<String, String> country_name  = new HashMap<String, String>(); 
    Map<String, String[]> country_idd  = new HashMap<String, String[]>(); 
    Map<String, String[]> country_cid  = new HashMap<String, String[]>(); 

    public iso_countries(){  
     country_name.put("nl",   "Netherlands");  
     country_idd.put("nl",  new String[]{"+31"}); 
     country_cid.put("nl",  new String[]{"#31#", "*31#"}); 
     setData(country_name, country_cid, country_idd); 
     // 249 * 4 lines more and later... 
    }//end method 

    public void setData(Map country_name, Map country_cid, Map country_idd){ 
     country_data.put("name", country_name); 
     country_data.put("idd", country_idd); 
     country_data.put("cid", country_cid); 
    }//end method 

    public String getCountryName(String countryCode){ 
     String name  = country_name.get(countryCode); 
     return name; 
    }//end method 

    public String[] getCountryIdd(String countryCode){ 
     String prefix[] = country_idd.get(countryCode); 
     return prefix; 
    }//end method 

    public String[] getCountryCid(String countryCode){ 
     String cid[] = country_cid.get(countryCode); 
     return cid; 
    }//end method 
}//end class 
+0

你想在HashMap像行爲在PHP中,或者你會在Java中實現代碼? –

+3

爲什麼您的列表中有國家代碼和索引? '$ country_data [「我們」]沒有完美的工作嗎? –

+1

只是爲了評論你的PHP代碼:它甚至沒有任何意義,在''語言''索引中的值類型可以完全不同,一旦一個字符串,一旦數組...你應該決定你喜歡,並堅持下去。混合類型表示一種非常糟糕的編碼習慣,它會使你的代碼不穩定。編輯:@Brendan龍:是的,這也是一個很好的通知。 – Sk8erPeter

回答

8

可以存儲陣列作爲HashMap值:

HashMap<Integer,String[]> hm = new HashMap<Integer,String[]>(); 
hm.put(1, new String[]{ "a", "b" }); 

至於具有「多維」鍵,就可以永遠在一起了一類包裝他們。另一種雖然很難看的解決方案將是HashMaps的HashMaps。

+1

如果你的鍵是連續的整數,爲什麼不使用數組或列表而不是地圖? –

+0

謝謝,我選擇這個作爲我的解決方案。我其實選擇了醜陋的解決方案,並使用HashMaps的HashMaps。我稍後會發布我的代碼並解釋。 – slinden77

12

也許我誤解了你的問題,但爲什麼不創建你自己的對象來保存數據,然後將它們存儲在HashMap?

Java是一種面向對象的語言,所以爲什麼不使用它最着名的設施:對象!

+4

也許是因爲經過多年Java經驗,您可能會學習PHP,並發現關聯數組是您曾經搜索過的對象。它們非常酷,因爲您只需將它們從數據庫中直接填充,然後在GUI中正確訪問它們。不需要Java數據模型,因此至少減少20%的工作量。你改變你的洞數據庫?沒問題,如果使用關聯數組,那麼舊的Java GUI仍會運行。你只需要從新的數據庫中填充相同的數組。最後,它是關於創建哈希映射數組而不是像您所提議的那樣的對象哈希映射。編程是一門藝術。 ;) – Marcus

+0

是的,實現這麼簡單的工作只需要很多工作 – slinden77

+0

@Marcus這是一個很好的觀察。以前沒有想過那個。 – kevin628

11

PHP中的數組實際上是一個散列,而不是一個數組。

在java中使用正確的東西是一個HashMap。您還可以通過在其中存儲數組或列表來將多個數值存儲在Hashmap中。所以HashMap<String, HashMap<String, Object>Hashmap<String, List<Object>>可能會幫助你。

當您使用多維數組時,您必須使用整數作爲鍵。

2
Map<String, Object> map = new HashMap<String, Object>(); 

現在,而不是您所在的數組列表,在正常情況下,您將只將字符串作爲值。

另一種方法是使用值對象,它存儲你給它的任何東西。

public class ValueObject { 

    private Map<String, List<Object>> dataHolder = null; //getter, setter 
} 

Map<String, ValueObject> map = new HashMap<String, ValueObject>(); 
5

正確的方法是使用Country對象:

class Country { 
    // Might want these private with getters and/or setters 
    public String currency; 
    public Set<String> languages; 

    // String...languages is like String[] languages, except you can pass the 
    // arguments in like new Country("Euro", "Dutch", "German") 
    // instead of new Country("Euro", new String[] { "Dutch", "German" }) 
    // It's purely stylistic 
    public Country(String currency, String... languages) { 
     this.currency = currency; 
     this.languages = new HashSet<String>(); 
     for(String language : languages) { 
      this.languages.add(language); 
     } 
     // or this.languages = new HashSet<String>(Arrays.asList(languages)); 
    } 
} 

void someFunction() { 
    Map<String, Country> countries = new HashMap<String, Country>(): 
    countries.put("us", new Country("US Dollar", "English", "Spanish")); 
    countries.put("nl", new Country("Euro", "Dutch")); 
} 

你可以通過嵌套列表和地圖,以爲什麼使用Java,如果你不打算使用編譯器提供的工具做到這一點?

+1

這是正確的想法。我建議'languages'成員字段或者是'Set '或者'List '而不是數組。在構造函數中,可以遍歷語言arg,將它們一次添加到設置的一個,或者使用'Arrays.toList()'。 –

1

另外,如果您對國家,貨幣和語言的信息可以被靜態定義,你可以把所有的在集枚舉:

public enum Language { 
    EN, ES, FR; 
} 

public enum Currency { 
    USD, GBP, CAD; 
} 

public enum Country { 

    US(USD, EN), UK(GBP, EN), CAN(CAD, EN, FR); 

    private final Language[] languages; 
    private final Currency currency; 

    Country(Currency currency, Language... languages) { 
     this.currency = currency; 
     this.languages = Arrays.copyOf(languages, languages.length); 
    } 

    public Currency getCurrency() { 
     return this.currency; 
    } 

    public Collection<Language> getLanguages() { 
     return asList(this.languages); 
    } 
} 

然後,你可以很容易地做一些事情,如:

Map<Integer, Country> data = new HashMap<Integer, Country>(); 
data.put(0, US); 
data.put(1, UK); 

Currency currency = data.get(0).getCurrency(); 
Collection<Language> langs = data.get(0).getLanguages(); 

System.out.println(currency); 
System.out.println(langs);