10

我遇到了很多人似乎面临来自 PHP 的相同问题,缺乏一个体面且易于使用的关联数组解决方案。我在这里读过基本上都建议使用HashMap的问题,像这样Q:Java associative-array

但是,我认为提到的解决方案不会解决我的问题。我会解释的。

我有一个包含 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 解决方案所困扰,但我仍然看不到这将如何让我存储数组,我确信我忽略了一些简单的东西。一个基于我的例子会很棒!

更新

我选择了 HashMaps of HashMaps 的原因是我需要能够轻松地监督一切,并在需要时更改几行值。这很灵活,我可以轻松地根据国家代码、语言获取国家名称,或者我可以在需要时获取 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
4

6 回答 6

12

也许我误解了你的问题,但为什么不创建自己的对象来保存数据,然后将它们存储在 HashMap 中呢?

Java 是一种面向对象的语言,所以为什么不使用它最著名的工具:对象!

于 2012-06-01T19:45:32.683 回答
11

PHP 中的数组实际上是一个散列,而不是数组。

在 java 中正确使用的是 HashMap。您还可以通过在其中存储数组或列表来将多个值存储在 Hashmap 中。所以HashMap<String, HashMap<String, Object>Hashmap<String, List<Object>>可能会帮助你。

使用多维数组时,必须使用整数作为键。

于 2012-06-01T19:45:33.020 回答
8

您可以将数组存储为 a 的值HashMap

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

至于具有“多维”键,您始终可以将它们与类一起包装。另一个虽然丑陋的解决方案是拥有HashMaps of HashMaps。

于 2012-06-01T19:46:56.060 回答
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?

于 2012-06-01T19:50:02.803 回答
2
Map<String, Object> map = new HashMap<String, Object>();

现在您放置 List 而不是 Array,在正常情况下您只需放置 String 作为值。

另一种方法是使用值对象来存储你给它的任何东西。

public class ValueObject {

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

Map<String, ValueObject> map = new HashMap<String, ValueObject>();
于 2012-06-01T19:46:34.783 回答
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);
于 2012-06-01T20:12:55.250 回答