3

How can I write the following method using switch case instead of if else

public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException 
{

    currentElement = true;

    if (localName.equals("maintag"))
    {
        /** Start */ 
        sitesList = new SitesList();
    } else if (localName.equals("website")) {
        /** Get attribute value */
        String attr = attributes.getValue("category");
        sitesList.setCategory(attr);
    }

}

9 Answers 9

7

In your case, you should use ENUM, not a string literal, and then you can refer to enum in a switch case:

Further reference

Sign up to request clarification or add additional context in comments.

Comments

5

Switch using Strings

You can't. Java 1.6 doesn't support switch statements with Strings.

Java 1.7 possibly will (it is one of the features of Project Coin), but for 1.6 you should either use an enum (best choice) or otherwise use a map.

Pseudo-switch using a Map

Here's how:

Create an interface:

interface SiteListProvider{
    SitesList provide();
}

Now create a Map that maps Strings to different implementations of SiteListProvider:

Map<String, SiteListProvider> providers =
    new HashMap<String, SiteListProvider>();
providers.put("foo", new SiteListProvider(){
    public SitesList provide(){
        return new SiteList("foo", "bar", "baz");
    }

});
providers.put("phleem", new SiteListProvider(){
    public SitesList provide(){
        return new SiteList("otherstuff");
    }
});

And now use it like this:

SiteList siteList = providers.get(localName).provide();

Comments

2

switch in most languges, java included, only works with datatypes that are integers at heart: http://download.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

You can't use switch with strings. Sorry.

3 Comments

Is an enum an integer at heart? In a certain way it is, I guess :-)
One exception is PHP where the switch statement works equally well with strings. I think part of the problem is that String in Java is not a primitive type and comparing the reference makes no sense. I would wish that == mean to compare the Objects as with .equals() and there was a special method to compare the references, since comparing objects with .equals() is the most common thing to do. Also the switch statement could have been smart enough to call .equals() for Objects. Sadly it doesn't work in this way.
@stivlo Java's switch works with compile-time constants. Using equals() would mean runtime evaluation, which could lead to all kinds of funny side effects. Soon there will be switch with string literals (which are compile-time constants), and that is good. But what you are describing does just not fit into the static nature of Java.
1

In Java 7 you will be able to use strings, for now youc an use an enum like this.

enum LocalName {
    maintag, website, UNKNOWN;
    public static LocalName lookup(String text) {
        try {
            return valueOf(text);
        } catch(Exception e) {
            return UNKNOWN;
        }
     }
}

switch(LocalName.lookup(localName)) {
    case maintag:
        /** Start */ 
        sitesList = new SitesList();
        break;
    case website:
        /** Get attribute value */
        String attr = attributes.getValue("category");
        sitesList.setCategory(attr);
        break;
}

2 Comments

I'd consider separating the enum names and string values, to allow for extra functionality. See also: Reverse enum 'pattern' (?). You could store the keys (strings) and their enum counterparts in a Map too for very fast lookups.
I am pretty sure valueOf() uses a Map. It would be faster if you have alot of misses. Do you have any performance comparisons?
0

If you're really receiving localName as a String, you can't. switch only works with byte, short, char, int, and enums (reference).

Comments

0

You can't avoid the if else since:

A switch works with the byte, short, char, and int primitive data types. It also works with enumerated types (discussed in Classes and Inheritance) and a few special classes that "wrap" certain primitive types: Character, Byte, Short, and Integer (discussed in Simple Data Objects ).

From: http://download.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

Comments

0

If you know what the possible answers are you could do something like:

public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException 
        {

        currentElement = true
        switch(localName.charAt(0)) {
           case 'm':
               sitesList = new SitesList();
               break;
           case 'w':
               String attr = attributes.getValue("category");
               // etc.
               break;
           default:
               break;
        }
        ...
}

This only works if you know the expected values and they all need to have a different first character! This solution will not earn a beauty price but is AN answer to your question ;-)

1 Comment

Would not recommend this approach, it's not extensive enough (limited only to first characters), limits in usage, and might even cause the XML to be loaded to get a constraint that all tags should have a unique first character.
0

If you can replace the String by an enum, do it - as already said. If you can't, you can get the enum for String like follows:

Declaration and initialization

enum LocalName {MAINTAG, WEBSITE}
private final static Map<String, LocalName> localNameForString
    = new HashMap<String, LocalName>();
static {
    for (LocalName n : LocalName.values()) {
        localNameForString.put(n.name().toLowerCase(), n);
    }
}

Usage

LocalName n = localNameForString.get(localName);
if (n==null) {
   // do something
} else  switch (n) {
    ...
}

It's a bit verbose, but not really bad, and working with enums is a pleasure. :D

Comments

0

I solve this problem by changing the "switch" for "if" anything like this:

if (mystring.equals("string")
   thisstring="vi";

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.