Вопрос: Ассоциативные массивы и Java


Я столкнулся с той же проблемой, с которой сталкиваются многие люди из PHP, отсутствие подходящего и простого в использовании решения ассоциативного массива. Я читал здесь вопросы, которые в основном все предлагали использовать HashMap, вроде этого Q: 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, но я все еще не вижу, как это позволит мне хранить массивы, я уверен, что я пропускаю что-то простое. Пример, основанный на моей, был бы замечательным!

ОБНОВИТЬ

Я решил пойти на HashMaps из 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

9


источник


Ответы:


Вы можете хранить массивы как значения HashMap:

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

Что касается наличия «многомерных» ключей, вы всегда можете обернуть их вместе с классом. Другим, хотя и уродливым, решением было бы HashMapс HashMaps.


8



Возможно, я не понимаю вашу проблему, но почему бы не создать свой собственный объект для хранения данных, а затем сохранить их в HashMap?

Java - объектно-ориентированный язык, поэтому почему бы не использовать его самое известное средство: объекты!


12



Массив в PHP на самом деле является хешем, а не массивом.

Правильная вещь для использования в java - это HashMap. Вы также можете хранить значения большого количества в Hashmap, сохраняя в нем массивы или списки. Так HashMap<String, HashMap<String, Object> или Hashmap<String, List<Object>> может помочь вам.

Когда вы используете многомерные массивы, вы должны использовать целые числа в качестве ключа.


11



Правильный способ - использовать объект 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, если вы не собираетесь использовать инструменты, которые дает вам компилятор?


5



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

теперь вместо Array вы помещаете List, в обычных случаях вы просто ставите String в качестве значения.

Другим подходом будет использование объекта ценности, в котором хранятся все, что вы ему дали.

public class ValueObject {

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

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

2



В качестве альтернативы, если ваша информация о странах, валютах и ​​языках может быть определена статически, вы можете поместить все это в набор перечислений:

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

1