【问题标题】:Associative arrays and Java关联数组和 Java
【发布时间】:2012-06-07 01:20:33
【问题描述】:

我遇到了很多人似乎在使用 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 的 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

【问题讨论】:

  • 您希望在 php 中实现类似 hashmap 的行为,还是在 java 中实现代码?
  • 为什么您的列表有国家代码和索引? $country_data["us"] 不是很好用吗?
  • 只是评论您的 PHP 代码:这甚至没有任何意义,'language' 索引中的值类型可以完全不同,一次是字符串,一次是数组......你应该决定你喜欢哪个,并坚持下去。混合类型表示一种非常糟糕的编码实践,它会使您的代码不稳定。编辑:@Brendan Long:是的,这也是一个很好的通知。
  • Java 与 PHP 不是同一种语言,您不应该使用相同的技术。在这里,具有强类型字段的“国家”对象的地图和列表将是更合适的解决方案。
  • @BrendanLong 是的,确实不需要数字索引。我目前正在阅读所有答案,仍在学习 Java,所以我什至很难掌握一些答案!谢谢大家,我将进一步调查并用已回答标记适当的 Q 并发布我的解决方案以供将来参考。

标签: java arrays multidimensional-array


【解决方案1】:

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

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

【讨论】:

  • 也许是因为在多年的 Java 经验之后,您可能会学习 PHP,并发现关联数组是您曾经搜索过的对象。它们更酷,因为您只需直接从数据库中填充它们,然后直接在您的 GUI 中访问它们。不需要 Java 数据模型,因此至少可以减少 20% 的工作量。你改变你的洞数据库?没问题,如果您的旧 Java GUI 使用关联数组,它仍然可以运行。您只需要从新数据库中填充相同的数组。最后,它是关于创建哈希映射数组而不是像您建议的对象的哈希映射。编程是一门艺术。 ;)
  • 是的,要实现这么简单的事情还需要做很多工作
  • @Marcus 这是一个很好的观察。之前没想到。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:
    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>();
    

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • 如果你的键是连续整数,为什么不使用数组或列表而不是映射呢?
      • 谢谢,我选择了这个作为我的解决方案。我实际上选择了丑陋的解决方案,并且正在使用 HashMaps 的 HashMaps。我稍后会发布我的代码并解释。
      【解决方案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?

      【讨论】:

      • 这是正确的想法。我建议 languages 成员字段是 Set&lt;String&gt;List&lt;String&gt; 而不是数组。在构造函数中,可以遍历语言 arg 以一次将它们添加到集合中,或者使用 Arrays.toList()
      【解决方案6】:

      或者,如果您可以静态定义有关国家、货币和语言的信息,您可以将所有这些信息放在一组枚举中:

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

      【讨论】:

        猜你喜欢
        • 2011-07-04
        • 2015-11-03
        • 2015-04-08
        • 1970-01-01
        • 2013-06-06
        • 1970-01-01
        • 2016-02-17
        • 2011-09-22
        相关资源
        最近更新 更多