Java相当于Perl的哈希值

sno*_*kin 8 java perl hash data-structures

由于超级灵活和方便,我一直在使用很多Perl哈希.例如,在Perl中我可以执行以下操作:

$hash{AREA_CODE}->{PHONE}->{STREET_ADDR}
Run Code Online (Sandbox Code Playgroud)

我想知道如何用Java完成同样的事情,我想它与HashMap有关?

谢谢,

tch*_*ist 18

由于超级灵活和方便,我一直在使用很多Perl哈希.例如,在Perl中,我可以执行以下操作: $hash{AREA_CODE}->{PHONE}->{STREET_ADDR} 我想知道如何使用Java完成相同的操作,我想它与HashMap有关?

Java代码近似于以下Perl代码:

my %hash;
$hash{AREA_CODE}{PHONE}{STREET_ADDR} = "221B Baker Street";
printf "Street address is %s\n", $hash{AREA_CODE}{PHONE}{STREET_ADDR};
Run Code Online (Sandbox Code Playgroud)

HashMap<String, HashMap<String, HashMap<String, String>>> hash =
    new HashMap<String, HashMap<String, HashMap<String, String>>>();

hash.put("AREA_CODE", new HashMap<String, HashMap<String, String>>());
hash.get("AREA_CODE").put("PHONE", new HashMap<String, String>());
hash.get("AREA_CODE").get("PHONE").put("STREET_ADDR", "221B Baker Street");

System.out.printf("Street address is %s\n",
    hash.get("AREA_CODE").get("PHONE").get("STREET_ADDR"));
Run Code Online (Sandbox Code Playgroud)

这不是特别的吗?:)

我说'近似'有很多原因.其中之一就是在Java中,你只会因为想要在Java的下一行上完成相当于这个非常直接的Perl代码而对极端中风这一点感到沮丧:

$hash{AREA_CODE}{PREFIX} = 800;
Run Code Online (Sandbox Code Playgroud)

如果你想要Perl在这样的事情上的灵活性和便利性,Java根本就不会给你.更糟糕的是,它的游击队员甚至会因为表达这种愿望而谴责你.

  • 恕我直言,你的Java代码 - 在一般情况下 - 有些不正确(尽管它是100%正确的字面翻译示例Perl代码).它不会检查AREA_CODE键是否已映射到有效的散列映射(如果您假设"刚声明"为空容器的特殊情况,则可以;但如果您不认为那么会中断).对于值检索也是如此 - 它不检查get("AREA_CODE")的值是否为空.这意味着 - 在一般情况下 - 设置和获取三维嵌套散列哈希散列的Java相当于甚至比你的更长和更丑. (2认同)

DVK*_*DVK 6

首先,您的特定示例($hash{AREA_CODE}->{PHONE}->{STREET_ADDR}),使用硬编码字符串作为哈希键,在迈克尔卡尔曼指出的Java中并不是真正有用的数据结构 - 它应该存储为具有属性的类(并且说实话它是一个概念中的数据结构不好 - 像这样的数据更可能是一组手机,而不是手机的哈希值.

其次,假设你真正的意思$hash{$AREA_CODE}->{$PHONE}->{$STREET_ADDR},看起来每个人的Java代码到目前为止都没有实现通用的等效代码 - 代码都假设Java哈希是为了存储示例而新初始化的,或者完全填充了检索示例(换句话说,作为leonbloy)的答案指出,缺少自动修复功能).

正确的代码mimiquing autovivification是:

// This method will ensure that hash-of-hash-of-hashes structure exists of a given set of 3 keys.
public HashMap<String, HashMap<String, HashMap<String, Object>>>
 autovivification_3rd_level (
           HashMap<String, HashMap<String, HashMap<String, Object>>> hash
         , String AREA_CODE, String PHONE, String STREET_ADDR) {
    if (hash == null) {
        hash = new HashMap<String, HashMap<String, HashMap<String, Object>>>();
    }
    if (!hash.contains(AREA_CODE) || hash.get(AREA_CODE) == null) {
        hash.put(new HashMap<String, HashMap<String, Object>>());
    }
    HashMap<String, HashMap<String, Object>> AREA_CODE_hash
         = (HashMap<String, HashMap<String, Object>>) hash.get(AREA_CODE);
    if (!AREA_CODE_hash.contains(PHONE) || AREA_CODE_hash.get(PHONE) == null) {
        AREA_CODE_hash.put(new HashMap<String, Object>());
    }
    return hash;
}

////////////////////////////////////////////////////////////////////////////////////    

// Equivalent to Perl's "$hash{$AREA_CODE}->{$PHONE}->{$STREET_ADDR} = value;"
public Object put_3d_level_hash(
          HashMap<String, HashMap<String, HashMap<String, Object>>> hash
        , String AREA_CODE, String PHONE, String STREET_ADDR,
        , Object value) {
    hash = autovivification_3rd_level(hash, AREA_CODE, PHONE, STREET_ADDR);
    return hash.get(AREA_CODE).get(PHONE).put(STREET_ADDR, value);
}
put_3d_level_hash(hash, AREA_CODE, PHONE, STREET_ADDR, obj);

////////////////////////////////////////////////////////////////////////////////////    

// Equivalent to Perl's "$var = $hash{$AREA_CODE}->{$PHONE}->{$STREET_ADDR}"
public Object get_3d_level_hash(HashMap<String, HashMap<String, HashMap<String, Object>>> hash
                       , String AREA_CODE, String PHONE, String STREET_ADDR) {
    hash = autovivification_3rd_level(hash, AREA_CODE, PHONE, STREET_ADDR);
    return hash.get(AREA_CODE).get(PHONE).get(STREET_ADDR);
}
Object obj = get_3d_level_hash(hash, AREA_CODE, PHONE, STREET_ADDR);
Run Code Online (Sandbox Code Playgroud)


leo*_*loy 5

请参阅Map接口及其实现,特别是HashMap.

请注意,Java没有Perl的自动生成(方便但危险的功能)

hash.get("areaCode").get("phone").get("streetAdr")
Run Code Online (Sandbox Code Playgroud)

如果例如get(phone)返回null,则会抛出异常.还要注意你不应该为具有固定名称("属性")的东西使用哈希,你应该用它的getter和setter来定义你自己的类.