3
\$\begingroup\$

I have a Java class which has to be generated only once for all the objects that I have - it is a small program. This singleton class holds a mapping of characters. I Googled stack overflow and found that using enum is the most safest way to create a singleton class as Josh Bloch explained in his Java book.


I also read some reviews that singletons are not good. But for my scope I think I need one. So my code is:

public enum  SingletonClassA {
    INSTANCE;
    private static Map<Character, Character> instance;
    static {
        Map<Character, Character> aCharMap = new HashMap();
        aCharMap.put('a', 'e');
        aCharMap.put('o', 'u');
        // in order to keep short I erased other puts.
        instance = Collections.unmodifiableMap(aCharMap);
    }

    public static Map<Character, Character> getInstance() {
        return instance;
    }
}

And in order to reach the elements of this HashMap I use

SingletonClassA.INSTANCE.getInstance().containsKey(aLetter);

Am I creating this singleton class correctly? Do I also need to create a private constructor?

If you have any suggestions about using another data structure for this case please recommend it, write the reasons also.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ "I also read some reviews that singletons are not good. But for my scope I think I need one. " - what is your scope? You don't mention this in your question and your class names are not very descriptive either - bordering example code. FYI, there is (almost) never a need for a singleton. \$\endgroup\$
    – Dan
    Commented Oct 1, 2015 at 11:22
  • \$\begingroup\$ May we know what is counter used for? Is this just supposed to be a static, read-only Map? Can you elaborate more on how the Map is being used and called, say inside some methods of your codebase? \$\endgroup\$
    – h.j.k.
    Commented Oct 1, 2015 at 11:27
  • \$\begingroup\$ Sorry, my mistake. I deleted it. \$\endgroup\$ Commented Oct 1, 2015 at 13:35

1 Answer 1

4
\$\begingroup\$

Despite some other comments, I believe there are times when a singleton is very appropriate, and a powerful tool. The best practice, in Java, since the introduction of enums, is to use them for singletons.

But, your implementation is broken.

When using an enum as a singleton, you should treat the enum as a regular-ish class, and do everything in instance methods, and not have any static content. Then, by declaring just one member in the enum, you get just one instantiation.... always.

So, your code would be better as:

public enum SingletonClassA {
    INSTANCE;

    private final Map<Character, Character> characters;

    // private constructor
    SingletonClassA() {
        Map<Character, Character> aCharMap = new HashMap();
        aCharMap.put('a', 'e');
        aCharMap.put('o', 'u');
        // in order to keep short I erased other puts.
        characters = aCharMap;
        counter++;
    }

    public boolean containsKey(char letter) {
        return characters.containsKey(letter);
    }
}

Your use case then becomes:

SingletonClassA.INSTANCE.containsKey(aLetter);
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.