Skip to main content

switch case string

15 replies [Last post]
don_t
Offline
Joined: 2005-04-01

There's been some discussions for extending switch/case to objects. What about allowing integral or String objects only for switch/case as in C#?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
golly
Offline
Joined: 2005-05-11

"icase" should just be the same as String.compareToIgnoreCase(). When we need anymore functionality beyond that, i think normal if/else statements should be used. I like the idea of switch with strings because I think there are a lot of situations where they would be useful but i don't think it should be a TOTAL replacement for if/else.

For eg, i'd like to use it for command args or something but I wouldn't use it if I was comparing two Japanese strings without differentiating between hiragana / (full+half width) katakana.

ulfzibis
Offline
Joined: 2005-02-18

I would prefer this:
[code]switch( arg) {
case equals("-e") : error_checking=true; break;
case equals("-E") : externalize=true; break;
case equalsIgnoreCase("start") : setOperation(Operations.START); break;
case equalsIgnoreCase("stop") : setOperation(Operations.STOP); break;
}[/code]
For reasons, see:

http://forums.java.net/jive/thread.jspa?threadID=504

ryan_ernst
Offline
Joined: 2005-05-11

Why do you need to add this functionality to case statements? There is nothing you have described that can't be done with a series of if-elseif blocks. I understand that you want the added speed of a case statement, but case statements are fast because they only deal with single characters. By adding the ability, for instance, to do equalsIgnoreCase within a case statement, you add complexity to every check. The equalsIgnoreCase method must be called, just as it would be in an if-elseif block. The normal case statement has the ability to map the input directly to the output. However, with equalsIgnoreCase you cannot do this because you cannot map every possible input to that case. For instance, consider

case equalsIgnoreCase("stop") : doSomething(); break;

The possible inputs that should map to this case are:
stop
stoP
stOP
sTOP
STOP
...

There are many more (16 I believe). And this is with a small word. Because there are so many possible ways to match case insensitive versions of "stop", a modified case statement would have to directly map every possible version of its case with the intended instruction address. And even if this could be done in polynomial time (the list of words grows exponentially with 2^n), generating the mappings could take a very long time and a lot of memory.

ulfzibis
Offline
Joined: 2005-02-18

[u]Why do you need [b]java[/b]? There is nothing that can't be done with a [b]assembler[/b].[/u]

You only have to type [i]some more lines[/i] ;-) (as you have to do by using if-then-else rather than switch-case).

rickcarson
Offline
Joined: 2004-03-04

Isn't this one of the 'compelling' reasons for having Enum? To use it in Case statements?

alexlamsl
Offline
Joined: 2004-09-02

I think I can understand what all of you are getting at here, so may I summarise and comment at the points:

1) I think the primary argument for extending the use of switch statements here is the ease of development, and even with the better optimisation chances. This sounds good, and in which case we should somehow extend this in such a way that all Immutable objects can use this construct (String, Integer, BigDecimal etc...)

2) As for the case-sensitivity, or pattern-matching in general, could be done specifically for String objects in a much similar way that auto-(un)boxing works in Tiger. But then bear in mind we would have (slightly, at least) missed the optimisation point above.

How is that? =)

terkans
Offline
Joined: 2004-09-17

> 1) I think the primary argument for extending the use
> of switch statements here is the ease of development,
> and even with the better optimisation chances. This
> sounds good, and in which case we should somehow
> extend this in such a way that all Immutable objects
> can use this construct (String, Integer, BigDecimal
> etc...)

So how do you detect an Immutable object? If it's just limited to specific core classes, people will still complain that their own immutables cannot be used.

alexlamsl
Offline
Joined: 2004-09-02

Oh when I speak of that of course I mean we will need to add the Immutable feature into the language as well...

foofoofoo
Offline
Joined: 2005-04-23

what's an example of when you would use this? an example that couldn't be better implemented in another way?

leto293
Offline
Joined: 2005-05-13

Just joined, so sorry for posting so late. This is something I have desired also. An example may be:

public static void processArg(String arg)
{
switch (arg)
{
case "-dofirst":
// Do first action
break;
case "-doanother":
// Do another action
break;
// etc...
}

The point here being, that although it can be done with multiple 'if' statements, or a HashMap lookup, the compiler has the advantage, it can pre-calculate the hash values, and create an optimized combination of switch on hash value and hard comparison with if statements. Most of the time, no matter what the size of the switch, it would boil down to the switch itself, and a single equals comparison.

Of course, it gets a little more complicated if you want case insensitivity, but there are ways.

golly
Offline
Joined: 2005-05-11

maybe we could use "icase" instead of case for case-Insensitive matches.

eg:

swtich (arg) {
case "-e": error_checking=true; break;
case "-E": externalize=true; break;
icase "start": setOperation(Operations.START); break;
icase "stop": setOperation(Operations.STOP); break;
}

lucretius2
Offline
Joined: 2004-12-19

There's no one type of case insensitivity, because it depends on your locale. ('I' and 'i' are not equivalent characters in Turkish.) So there's probably no easy or useful way to build it into switch statements.

leto293
Offline
Joined: 2005-05-13

I had a hunt around the String class, and yes, in toLowerCase there is a locale specific version. But I think the semantics of equalsIgnoreCase are more pertinent here, and oddly enough it does not have locale specific behaviour. What it does have is a few hard coded region specific clauses, but the logic is static and predictable independent of the host locale, depending only on the ordinal values of the string itself.

As if life could be that easy though. One of those region specific hacks is because Georgian characters have rules for case conversion, which means that even if a toUpperCase on a pair of characters fails to match, the toLowerCase on them may still match.

It may be possible though, knowing this, to product a case insensitive hashCode value, that as a part of its calculated takes account of the special rules for Georgian characters. After that, the final equals check is replaced with an equalsIgnoreCase.

The main caviets here are that the rules for case insensitivity should be relatively static, and a switch must be all case insensitive or not. The second one I can live with, but the first is I think going a bit too far.

Though this may sound the death knell for case insensitive switching as a language feature, it does not as an idea. If a person needs to swtich case insensitively, switch (str.toLowerCase()) will do the job nicely. Since the cases statements are static, it's not hard to see problems before they happen.

Summery: No case insensitivity, because it's difficult to plan static code for a dynamic future, and you could do it with str.toLowerCase() anyway.

fuerte
Offline
Joined: 2004-11-22

What about allowing integral or String value comparison with == as in C#? :-)

Sorry couldn't resist.

ulfzibis
Offline
Joined: 2005-02-18