static hashtable with conent?

K

Kevin

Did not find out the answer after some google:

how can we create a static hashtable with some initial values there?

static Hashtable ht = new Hasthable();

will only create a empty one. Suppose I want to put some Integer
values as keys and values of this hashtable, how can I do that?

The reason for it is that I am writing a "utility" class, with all the
functions as static. These functions will need to check a fixed
hashtable for some operations.

Thanks a lot. :)
 
L

Lew

Kevin said:
how can we create a static hashtable with some initial values there?

static Hashtable ht = new Hasthable();

will only create a empty one. Suppose I want to put some Integer
values as keys and values of this hashtable, how can I do that?

The reason for it is that I am writing a "utility" class, with all the
functions as static. These functions will need to check a fixed
hashtable for some operations.

Use a static initializer.

Use HashMap, not Hashtable, usually. This is especially true if, as seems to
be true for you, no one is writing to the table.

If that is the case, use a static method to return the Map (as a Map, not a
HashMap) via Collections.unmodifiableMap(). Otherwise client code will be
able to alter the contents of your Map.
 
L

Lars Enderin

Kevin skrev:
Did not find out the answer after some google:

how can we create a static hashtable with some initial values there?

static Hashtable ht = new Hasthable();

will only create a empty one. Suppose I want to put some Integer
values as keys and values of this hashtable, how can I do that?

The reason for it is that I am writing a "utility" class, with all the
functions as static. These functions will need to check a fixed
hashtable for some operations.

Write the code to initialize the table inside a
static { ... }
block. Note that Hashtable is not recommended. Use some version of Map
instead.
 
M

Mike Schilling

Kevin said:
Did not find out the answer after some google:

how can we create a static hashtable with some initial values there?

static Hashtable ht = new Hasthable();

will only create a empty one. Suppose I want to put some Integer
values as keys and values of this hashtable, how can I do that?

Use a static init block (And use a HashMap; Hashtable is obsolete)

static Map map;
static
{
map = new HashMap();
map.put("if", IF_TOKEN);
map.put("else", ELSE_TOKEN);
...
}
 
O

Owen Jacobson

Use a static init block (And use a HashMap; Hashtable is obsolete)

static Map map;
static
{
map = new HashMap();
map.put("if", IF_TOKEN);
map.put("else", ELSE_TOKEN);
...
}

There is a trick for emulating (sort of) map literals in Java that
might be useful here:

static Map<String, Whatever> map = new HashMap<String, Whatever> () {{
put ("if", IF_TOKEN);
put ("else", ELSE_TOKEN);
// ...
}};

It does have the cost of requiring one more class to be loaded. It
will also confuse reflection-based code that expects the 'map' field to
_be_ a specific subtype rather than _assignable to_ a specific subtype.
OTOH, I find both of those concerns are rarely important in my own
code.

Cheers,
O
 
M

Mike Schilling

Owen said:
There is a trick for emulating (sort of) map literals in Java that
might be useful here:

static Map<String, Whatever> map = new HashMap<String, Whatever> () {{
put ("if", IF_TOKEN);
put ("else", ELSE_TOKEN);
// ...
}};

It does have the cost of requiring one more class to be loaded. It
will also confuse reflection-based code that expects the 'map' field
to _be_ a specific subtype rather than _assignable to_ a specific
subtype. OTOH, I find both of those concerns are rarely important in
my own code.

It'll also confuse the hell out of anyone who's never seen it before. I got
it eventually, but it's not really obvious that "{{" introduces an init
block in an anonymous class.
 
O

Owen Jacobson

It'll also confuse the hell out of anyone who's never seen it before. I got
it eventually, but it's not really obvious that "{{" introduces an init
block in an anonymous class.

*grin*

That's about what my initial reaction to it was. It's also nowhere
near as elegant as Perl or Python's dictionary literals.
 
L

Lew

"Mike Schilling" said:
Owen said:
*grin*

That's about what my initial reaction to it was. It's also nowhere near
as elegant as Perl or Python's dictionary literals.

You could make it more "literal" by wrapping the assignment with a
Collections.unmodifiableMap(), no?

static Map<String, Whatever> map = Collections.unmodifiableMap(
new HashMap<String, Whatever> ()
{
{
put ("if", IF_TOKEN);
put ("else", ELSE_TOKEN);
// ...
}
}
);

If there's one thing I got from Owen's suggestion it's that I'll never know
everything there is to know about Java.

Ugly as it is to many people, Java's anonymous class syntax is bloody powerful.
 
P

Patricia Shanahan

Owen Jacobson wrote:
....
There is a trick for emulating (sort of) map literals in Java that might
be useful here:

static Map<String, Whatever> map = new HashMap<String, Whatever> () {{
put ("if", IF_TOKEN);
put ("else", ELSE_TOKEN);
// ...
}};

It does have the cost of requiring one more class to be loaded. It will
also confuse reflection-based code that expects the 'map' field to _be_
a specific subtype rather than _assignable to_ a specific subtype. OTOH,
I find both of those concerns are rarely important in my own code.

What is the advantage of this over the static initializer approach? It
is very clever, and I don't immediately see anything to compensate for
the cleverness.

Patricia
 
S

Stefan Ram

Patricia Shanahan said:
What is the advantage of this over the static initializer approach? It
is very clever, and I don't immediately see anything to compensate for
the cleverness.

It can be used, where an /expression/ for a map is wanted.

For example, in a call:

f( new HashMap(){{ put(a,b); put(c,d) }} );

. In the context »f( ... )«, a sequence of statements is not allowed.
 
M

Mike Schilling

Stefan said:
It can be used, where an /expression/ for a map is wanted.

For example, in a call:

f( new HashMap(){{ put(a,b); put(c,d) }} );

. In the context »f( ... )«, a sequence of statements is not allowed.

Or one could simply say

Map map = new HashMap();
map.put(a,b);
map.put(c,d);
f(map);

Or even introduce a private method to create and populate the map, if it's
considered important to distinguish that part of the code from the rest..

By the way, note that Patricia is (quite correctly here) using "clever"
disparagingly. That isn't done nearly often enough.
 
O

Owen Jacobson

Or one could simply say
Mike
Map map = new HashMap();
map.put(a,b);
map.put(c,d);
f(map);

Or even introduce a private method to create and populate the map, if it's
considered important to distinguish that part of the code from the rest..

By the way, note that Patricia is (quite correctly here) using "clever"
disparagingly. That isn't done nearly often enough.

In the context of a method call, I would prefer Mike's form. In the
context of initializing a map constant I think I'd prefer to keep the
initializer scoped to the map and only the map, rather than to the
containing class.
 
L

Lasse Reichstein Nielsen

Mike Schilling said:
Use a static init block (And use a HashMap; Hashtable is obsolete)

static Map map;
static
{
map = new HashMap();
map.put("if", IF_TOKEN);
map.put("else", ELSE_TOKEN);
...
}

I would prefer a static method returning the map:

static Map map = createMap();

private static final Map createMap() {
Map map = new HashMap();
map.put("if", IF_TOKEN);
map.put("else", ELSE_TOKEN);
}

Or perhaps create a builder:
static Map map = new MapBuilder(new HashMap()).put("if", IF_TOKEN)
.put("else", ELSE_TOKEN)
.toMap();
if it is something that is done often.

I would prefer not to use the clever anonymous subclass of HashMap
with an initializer. It's something that's bound to bite you in the
posterior sooner or later. E.g., if you try to send the map to another
process using serialization - then the receiver should also have the
same anonymous class available. That can be alleviated using
static Map map = new HashMap(new HashMap(){{
put("if", IF_TOKEN);
put("else", ELSE_TOKEN);
}});
i.e., using it more like a builder. Still far too clever to be readily
readable.


However, it seems that the actual problem being solved is a translation
between strings and some contstants/enums/whatever.
That the translation is performed by a map is an implementation detail.

I would create a method
static Token textToToken(String text) { //...
It could initialize its map lazily, or it could use a completely separate
apporach.

/L 'but Map literals would be nice :)'
 
L

Lew

Lasse said:
However, it seems that the actual problem being solved is a translation
between strings and some contstants/enums/whatever.
That the translation is performed by a map is an implementation detail.

If that's the case, then an enum with a well-crafted valueOf() would do the trick.
 
P

Patricia Shanahan

Mike Schilling wrote:
....
Or one could simply say

Map map = new HashMap();
map.put(a,b);
map.put(c,d);
f(map);

Or even introduce a private method to create and populate the map, if it's
considered important to distinguish that part of the code from the rest..

By the way, note that Patricia is (quite correctly here) using "clever"
disparagingly. That isn't done nearly often enough.

Maybe "disparagingly" is a bit stronger than I meant. I have really
mixed feelings about this type of thing.

On the one hand, I admire creativity, and enjoy solving puzzles. From
that point of view, the anonymous class version is just plain *fun*.

On the other hand, in real code I greatly prefer simplicity and
obviousness. Even if something clever looks shorter in a newsgroup
posting, it would often be longer in real code, because of the comment
explaining it.

Even for the call situation, I would go with the code Mike suggested or
its private method call equivalent.

This really comes down to a model of programming as writing that must
communicate its meaning to two very different audiences. One audience is
the compiler, and other programming tools. The other audience is all
programmers who will ever read the code, my future self included.

The two methods communicate equally well with the compiler. The method
Mike suggests perhaps communicates better with refactoring tools -
Eclipse could convert it between the in-line and method call versions.

But the really important issue is that many programmers will have to
stop and puzzle out the anonymous class version. I understood it once I
looked at it and thought about it, but I would not have read straight
through it, thinking only about whether the initial contents of the map
are appropriate, the way I would the simpler, more explicit versions.

Patricia
 
S

Stefan Ram

Kevin said:
will only create a empty one. Suppose I want to put some Integer
values as keys and values of this hashtable, how can I do that?

I have written a library to parse map expressions.
For example:

public final class Main
{ public static void main( final java.lang.String argv[] )
{
final IntMap map = new IntMap( "1=7 2=4" );
java.lang.System.out.println( map.valueOf( 1 )+ map.valueOf( 2 )); }}

/* prints:
11
*/

class IntMap
{ final java.util.Map map;

public IntMap( final java.lang.String arg )
{ this.map = de.dclj.ram.notation.unotal.RoomFromModule.room
// see http://www.purl.org/stefan_ram/pub/junotal_tutorial
( "< " + arg + " >" ); }

public int valueOf( final int arg )
{ return java.lang.Integer.valueOf
( this.map.get( java.lang.String.valueOf( arg )).toString() ); }}
 
M

Mike Schilling

Lew said:
If that's the case, then an enum with a well-crafted valueOf() would
do the trick.

Actually, mapping strings to constanxcts was my example of a map. The OP
never told us what his map was for.
 
L

Lew

Mike said:
Actually, mapping strings to constanxcts was my example of a map. The OP
never told us what his map was for.

It occurs to me that such a map could be part of the implementation of an
enum's valueOf() method.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

HashTable 26
Hashtable with initial values 7
Regarding use of ArrayList as value in Hashtable 9
Return HashTable 0
an array in a hashtable 15
Static code analysis tool 0
Hashtable with JDK1.5 6
About Hashtable... 11

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top