I\'ve been using a lot Perl hashes due to super flexibility and convenient. for instance, in Perl I can do the following:
$hash{AREA_CODE}->{PHONE}->{S
I've been using a lot Perl hashes due to super flexibility and convenient. for instance, in Perl I can do the following:
$hash{AREA_CODE}->{PHONE}->{STREET_ADDR}
I wondering how can I accomplish the same thing with Java, I guess it has something to do with HashMap?
The Java code which approximates the following Perl code:
my %hash;
$hash{AREA_CODE}{PHONE}{STREET_ADDR} = "221B Baker Street";
printf "Street address is %s\n", $hash{AREA_CODE}{PHONE}{STREET_ADDR};
is
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"));
Isn’t that special? :)
I say ‘approximates’ for many reasons. One of these is that in Java you’ll be frustrated to the point of extreme apoplexy merely for wanting to then do on the next line of Java the equivalent of this perfectly straightforward Perl code:
$hash{AREA_CODE}{PREFIX} = 800;
If you want Perl’s flexibility and convenience in things like this, Java simply isn’t going to give it to you. Even worse, its partisans will often berate you for even expressing such a desire.
If the hash keys are constant, why won't hash.getAreaCode().getPhone().getStreetAddr()
do? Keep in mind that either your getters or your constructors will need to handle default value generation.
You're probably going to want to go with Groovy if you want this sort of flexibility but still run within the JVM. tchrist likes to ignore the point that Java is strong-typed as opposed to dynamic-typed languages like Perl or PHP - and also likes to ignore that Java is an order of magnitude faster at running, but that's just me being a "partisan", apparently.
Java has hashes, but because of strong typing they're not quite as flexible as hashes in Perl. Multidimensional hashes are harder to work with. In Perl, you can just declare a hash and let autovivification create the nested hashes on demand.
my %hash;
$hash{a}{b} = 1;
In Java, you have to declare it to be a hash-of-hashes up-front.
Map<String,Map<String,Integer>> hash = new HashMap<String,HashMap<String,Integer>>();
hash.put("a", new HashMap<String, Integer>());
hash.get("a").put("b", new Integer(1));
For every extra dimension you need to add another nesting of Map<K,V>
to the declaration. Aside from being tedious, this isn't very OO.
See the Map interface and its implementations, specially HashMap.
Beware that Java doesn't have Perl's auto-vivification (handy but dangerous feature) so that
hash.get("areaCode").get("phone").get("streetAdr")
will throw an exception if, eg, get(phone) returns null. Beware also that you should not uses hashes for things that have fixed names ("properties"), you should define your own classes with its getters and setters.
I missed the perl hashes a lot in my work and made some ugly workarounds with hash classes.
Last week I had an idea to implement the whole thing in one PerlMap
class which use delimiters to access objects and foremost the Lists
zu access subsets.
It works fine with map.get(code:street:phone)
and map.put(code:street:phone,"123456789")
. To get a list of phonenumber you just use map.getList(code:street)
.
I've just started but use in my project now. It has no limitations of complexity :-) and you can choose the delimiter free. I put the whole stuff under http://www.jdeer.org. Have fun.