2012-06-01 14 views
9

私は同じ問題を抱えています。多くの人が、まともな使いやすい連想配列の欠如であるPHPから来ているようです。 私はこのQのように基本的にHashMapを使うことを提案した質問をここで読んだ。Java associative-array連想配列とJava

しかし、上記の解決策は私の問題を解決するとは思わない。私は説明します。

データを保存する250項目(国)のリストがあります。データの長さは定義されていません。つまり、「列」ごとに複数のエントリを保持できます。エントリがない場合もあります。

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"); 

だから時々私は時々、配列を格納しないようにしたいです。もちろん、文字列の代わりに1つのエントリだけを持つ配列でもかまいませんが、私はちょうど言っています。

したがって、問題は、配列をHashMapの配列に格納してフェッチする方法です。私は醜いHashMapソリューションに悩まされていることを理解していますが、これで配列を格納する方法がわかりません。単純なものを見落としていると思います。私に基づいた例が素晴らしいでしょう!

UPDATE

私は簡単にすべてを監督し、必要なときに値の数行を変更できるようにする必要があり、この理由ハッシュマップ のハッシュマップのために行くことにしました。これは柔軟性があり、国コードや言語に基づいた国名を簡単に取得できます。必要なときに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

PHPでハッシュマップのような動作が必要な場合や、Javaでコードを実装していますか? –

+3

リストに国コードとインデックスがあるのはなぜですか? '$ country_data [" us "]'は完璧に動作しませんか? –

+1

あなたのPHPコードにコメントするだけでは意味がありません。 '' language''インデックスの値の型は、文字列、配列のように全く違っている可能性があります。好きで、それに固執する。タイプを混在させると、実際にコードが正しくないことが示されます。コードが不安定になります。編集:@ブレンダンロング:はい、あまりにも良い通知です。 – Sk8erPeter

答えて

8

:「多次元」キーを備えなどについては

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

、あなたは常にクラスと一緒にそれらをラップすることができます。もう1つ、醜い解決策であっても、HashMapsがHashMapsである。

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

キーが連続した整数の場合は、マップではなく配列やリストを使用してみましょう。 –

+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>(); 

リストの代わりに、リストを配置します。通常は、値としてStringを配置します。

もう1つの方法は、あなたが与えたものを保存する値オブジェクトを使用することです。あなたがHashMapの値として配列を格納することができます

public class ValueObject { 

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

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

正しい方法は、国オブジェクトを使用するのですか?また

+1

これは正しいアイデアです。 'languages'メンバフィールドは配列ではなく、' Set 'または' List 'であることをお勧めします。コンストラクタでは、一度に1つずつargに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);