13
\$\begingroup\$

I need some help improving my code and wondering if I there is a better way to do the following:

StringBuilder buf = new StringBuilder(node.length() + 8);
        for (int i=0, n=node.length(); i<n; i++) {
            char c = node.charAt(i);
            String hexadecimal = "";
            switch (c) {
                case '"': hexadecimal = "\\22"; break;
                case '&': hexadecimal = "\\26"; break;
                case '\'': hexadecimal = "\\27"; break;
                case '/':  hexadecimal = "\\2f"; break;
                case ':': hexadecimal = "\\3a"; break;
                case '<': hexadecimal = "\\3c"; break;
                case '>': hexadecimal = "\\3e"; break;
                case '@': hexadecimal ="\\40"; break;
                case '\\':hexadecimal = "\\5c"; break;
                default: {
                    if (Character.isWhitespace(c)) {
                        hexadecimal = "\\20";
                    }else if(c > 127){
                        hexadecimal = "\\" + Integer.toHexString(c) + "\\";
                    }
                    else {
                        hexadecimal = String.valueOf(c);
                    }
                }
            }
            buf.append(hexadecimal);
        }
        return buf.toString();

I don't like how there is a switch statement which just sets a variable (hexadecimal) based on what the case is. I feel there is a better way to do this, such as by using a hash-map. I need the code to be flexible so that adding new characters and setting the hexadecimal is easy.

\$\endgroup\$
  • 2
    \$\begingroup\$ I'm not that versed in Java but isn't toHexString('#') == 22? So do you need the switch at all? \$\endgroup\$ – dreza Jul 6 '12 at 10:30
  • \$\begingroup\$ @dreza I'm assuming the formatting of "\22" is important. In which case Integer.toHexString('#') would get messy. But definitely a good idea. \$\endgroup\$ – Eva Jul 6 '12 at 11:36
29
\$\begingroup\$

A hash map is often a good idea for avoiding switch statements. It can be used in combination with the Strategy and Abstract Factory patterns, such as in these examples.

However, the Strategy Pattern is overkill for your problem. A simple hashmap would look like this

Map<Character, String> hexMap = new HashMap<Character, String>();
hexMap.put('\"', "\\22");
hexMap.put('\n', "\\20");
// puts more stuff in map...

 for (int i=0, n=node.length(); i<n; i++) {
     char c = node.charAt(i);
     buf.append(hexMap.get(c));
 }

But a quick googling of "java character to hexadecimal" produces these results. My favorite is

StringBuilder buf = new StringBuilder(node.length() + 8);

    for (int i = 0; i < node.length(); ++i) {
        char ch = node.charAt(i);
        buf.append(String.format("\\%1$x", (ch & 0xFFFF)));
    }

return buf.toString();

EDIT: Forgot to say, don't use magic numbers. I have no clue what the frack that 8 is doing in your program nor do I have to patience to try to deduce.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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