Software Development - Java, Ruby, Perl - RoboProg's

RoboProg's / Software Development

Last Month


Mar 17, 2009

Making Java More Dynamic

Recently, one of my coworkers asked me how to, using Java, initialize a Map using a single statement. I could not find anything in the java.util "Collections" API to do so. In Perl, you can do something like this:


my %COLORS =
    (
    'red' => 0xff0000,
    'green' => 0x00ff00,
    'blue' => 0x0000ff,
    );
However, in Java, the best you can do is something like this:

public static final
Map COLORS = new HashMap();  // <String, Integer> for purists
static
    {
    COLORS.put( "red", new Integer( 0xff0000) );
    COLORS.put( "green", new Integer( 0x00ff00) );
    COLORS.put( "blue", new Integer( 0x0000ff) );
    }
This is, shall we say, a bit more verbose than the Perl (or Ruby) initializer.

In response to this irritation, I decided to create a couple convenience routines to shorten Map initialization in Java code just a bit. You can download the .jar, which contains the source with example usage and other stuff. Repack the class file by iteself if this really bothers you, I guess.

The java test harness for the library looks like this:


    /**
     * Test harness for Hash utility.
     *  TODO:  junit?
     */
    public static
    void                main
        (
        String []       argv
        )
        {
        Map             result;
        
        // return a hash, er, map, instead of a list, peel out return vals
        result = demoFunc( "sub_command_A", Hash.newMap( new Object []
            {
            "in1",  "X",
            "in2",  new Integer( 0),
            "in3",  new Date()
            } ) );
        System.out.println( result);
        System.out.println( "out1: " + result.get( "out1") +
                "; out2: " + result.get( "out2") +
                "; out3: " + result.get( "out3") );
        }

    /**
     * Simulate doing something useful.
     */
    private static
    Map                 demoFunc
        (
        String          subCmd,
        Map             nameValArgs
        )
        {
        // pretend that there are dozens of lines of biz "logic" here
        return Hash.newMap( new Object []
            {
            "out2", nameValArgs.get( "in1"),
            "out3", nameValArgs.get( "in2"),
            "out1", nameValArgs.get( "in3")
            } );
        }
and the corresponding Ruby analogue:

require 'date'

# parallel code for Hash.main() (java version)
def main
    result = demo_func :sub_command_A,
        :in1    => 'X',
        :in2    => 0,
        :in3    => DateTime.new( 1999, 12, 31)  # default date is useless
    puts result
    puts 'out1: ' + result[ :out1 ].to_s +
            '; out2: ' + result[ :out2 ] +
            '; out3: ' + result[ :out3 ].to_s
end

# Simulate doing something useful.
def demo_func(
    sub_cmd,
    name_val_args
    )
    # pretend that there are dozens of lines of biz "logic" here
    return Hash[
        :out2   => name_val_args[ :in1 ],
        :out3   => name_val_args[ :in2 ],
        :out1   => name_val_args[ :in3 ] ]
end

FWIW, I've been meaning to write more lately, of course, but my laptop broke. My new laptop is a netbook with an Intel "Atom" chipset in it. I installed Ubuntu 8.04.2 on it, which worked fine. BUT THEN, the update installer decided to update the kernal, I foolishly agreed, only to become a member of the Bug 322867 club. Fortunately, there is a boot parameter you can add as a work-around, but it's still a time waster. I have been meaning to get back to the RoR plus OpenID stuff, but I still need to get my development environment set up on the new computer.



Contact me:
r
o
b
o
p
r
o
g
@
yahoo.com

Copyright 2009, Robin R Anderson