2012-06-01 44 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);