Zdenek has posted 3 posts at DZone. View Full User Profile

RefactoringNG: Bye bye, Hashtable

01.13.2011
| 7500 views |
  • submit to reddit

RefactoringNG (earlier article on DZone here) is a flexible and powerful Java refactoring tool, written as NetBeans module. Below you see how to use it when refactoring Hashtables.

The Hashtable class is a synchronized implementation of hash table and it is in the Java API since JDK 1.0. Since JDK 5, the Java API has also ConcurrentHashMap that is functionally equivalent to Hashtable but contrary to Hashtable enables concurrent operations. Concurrent operations result in better efficiency. So, it makes sense to "upgrade" the code from Hashtable to ConcurrentHashMap. In this article, we show how we can upgrade the code automatically.

We will use two rules. The first rule will replace fully qualified name java.util.Hashtable with java.util.concurrent.ConcurrentHashMap and the second rule will replace simple name Hashtable with ConcurrentHashMap.

// java.util.Hashtable -> java.util.concurrent.ConcurrentHashMap
 MemberSelect [identifier: "Hashtable"] {
    MemberSelect [identifier: "util"] {
       Identifier [name: "java"]
    }
 } ->
 MemberSelect [identifier: "ConcurrentHashMap"] {
    MemberSelect [identifier: "concurrent"] {
       MemberSelect [identifier: "util"] {
          Identifier [name: "java"]
       }
    }
 }
// Hashtable -> ConcurrentHashMap
 Identifier [elementKind: CLASS, qualifiedName: "java.util.Hashtable"] ->
 Identifier [name: "ConcurrentHashMap"]

If you want to try it, download the latest version of RefactoringNG and HashtableDemo.zip. Here are a few screenshots:

Published at DZone with permission of its author, Zdenek Tronicek.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Felix Martin replied on Fri, 2011/01/14 - 7:14am

I know the intention of the article is talk about RefactoringNG, but one of the problems i often see in code is not use the proper interfaces of the objects. If your demo class would have been written at first like follow, you would only need to change two lines.

 

package hastabledemo;

import java.util.Map;
import java.util.Hashtable;


public class Demo1 {

static Map<String, Integer> t = new Hashtable<String, Integer>();


static void getItem(Map<String, Integer> p, String s) {
Integer i = p.get(s);
System.out.pritnln(s + ": " + i);
}

static void putItem(Map<String, Integer> p, String s) {
p.put(s, Integer.valueOf(s));
}

static Integer getCacheItem(String s) {
return t.get(s);
}

static Map<String, Integer> getT() {
return t;
}

}

 

Christoph Kutzinski replied on Fri, 2011/01/14 - 8:57am

@Felix: so true.

BTW: Until Java 5 the 'best practice' to use synchronized maps was:

private Map map = Collections.synchronizedMap(new HashMap());

  Most of the time people used Hashtable it was not because they wanted to have a synchronized map, but just because they didn't know about HashMap or didn't care or both.

 

 

Zdenek Tronicek replied on Fri, 2011/01/14 - 9:38am

@Felix: right. But if I used the Map interface, I would not have shown that Hashtable in declaration would be changed as well. So this is why Hashtable is used as type. Thanks for the comment!

Philippe Lhoste replied on Fri, 2011/01/14 - 9:50am in response to: Christoph Kutzinski

We still have lot of Hashtable (and Vector and StringBuffer) in our (big!) legacy code.

Part of it was because some of the code was written before Java 1.2 (I think). Lot of it is because coders learned Java before Java 1.2... And apparently they find hard to shake their habits (still find some Hashtable in recent code).

Note that in 99% of cases, we don't need a synchronized version of these classes, so the refactoring would be to just use HashMap, ArrayList and StringBuilder, adapting the method calls in the process. Should we really need a synchronized version, it should be done with care...

Well, in some cases, we just cannot do the replacement, because it would change lot of classes as someone chose to make a public method returning a Vector (or another old class) and it is used through all the code base. Large scale refactorings are often avoided where I work, except in some periods (when starting a new major version).

Vidhyadharan De... replied on Fri, 2011/01/14 - 12:38pm in response to: Christoph Kutzinski

i have faced some production issues. Synchronized map is best .

Lutz Zimmermann replied on Sun, 2011/01/16 - 11:41am in response to: Vidhyadharan Deivamani

Would be great if you could enlighten us with the issues you ran into using the new concurrent implementation. thx!

Raveman Ravemanus replied on Tue, 2011/01/18 - 5:16am

Any chance for eclipse plugin?

Zdenek Tronicek replied on Tue, 2011/01/18 - 6:35pm in response to: Raveman Ravemanus

@Raveman: good question. We are not working on it at the moment. I rather want to focus on further development of the rules language.

Gregory Leb replied on Thu, 2011/12/01 - 11:58am

I would say leave this to the experts. Can’t say something more about Java except that I need to read more so that I can join to the intellectual discussion in this page. - Gregory Leb

Matt Coleman replied on Tue, 2012/06/12 - 1:25am in response to: Vidhyadharan Deivamani

I totally agree...Synchronized map is the way to go

website design buffalo

Mateo Gomez replied on Tue, 2012/06/12 - 11:56pm

im not so fond of hastables..this is great!! mexican dip recipes

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.