有没有一种方法可以将开关与String.contains("")集成?

13

我需要检查一个 String 对象是否包含多个子字符串,并根据结果执行不同的代码。目前我有一系列的 else if。如果可能的话,我想将其转换为 switch。有办法实现吗?

目前的代码:

 if (SomeString.contains("someSubString")) {

    . . . do something

 } else if (SomeString.contains("anotherSubString")) {

    . . . do something else

 } else if (SomeString.contains("yetanotherSubString")) {

    . . . do something even more different

 }  
 .
 .
 .

7
不行,你不能这样做。 - Rohit Jain
1
尽管Java SE 7已经实现了具有字符串案例的switch语句。 - Kamlesh Arya
Java 7 允许您使用字符串编写 switch-case,但仍然无法使用 contains 或任何返回布尔值的方法。在这里只能使用 if-else - ADTC
4
如果你有很多这样的测试,你可能想使用一个map<子字符串,动作>,并使用循环进行测试。 - Njol
你想做什么,为什么要那样做?你确定测试子字符串是最好的方法吗? - mrjink
4个回答

19

当我遇到这种情况,真的不想使用else if时,我会像这样做:

String[] cases = {"someSubString", "anotherSubString", "yetanotherSubString"};

int i;
for(i = 0; i < cases.length; i++)
    if(SomeString.contains(cases[i])) break;

switch(i) {
    case 0: //someSubString
        System.out.println("do something");
    break;
    case 1: //anotherSubString
        System.out.println("do something else");
    break;
    case 2: //yetanotherSubString
        System.out.println("do something even more different");
    break;
    default:
        System.out.println("do nothing");
}

当然,这种方法有一些缺点。首先,如果你在任何位置添加另一个字符串,所有的索引都会发生偏移,你必须手动进行更正。不过,我认为我曾经用过类似的方式一两次,觉得它使代码更易读。大概来说,这些索引在程序中具有某种意义,因此将0...someSubString与问题相关联。


如果你将不同的子字符串作为值,将其制作成枚举类型,你可以使用相同的思路,这样即使添加了子字符串也不会出错,因为switch语句是基于枚举而不是索引。 - mrjink
1
你的意思是类似于 for(...) if(SomeString.contains(currentEnum.getValue())) break;switch(currentEnum) {...} 这样的东西吗?如果是这样,我会使用 currentEnum.doSomething(); 而不是 switch - Silly Freak
不,我的意思是类似这样的枚举类型定义:enum Cases { SOME("someSubString"), ANOTHER("anotherSubString"), ...}。然后可以用以下代码进行遍历:Cases i; for (i : Cases.values()) if(SomeString.contains(i.getSubstring()) break; switch(i) { ... } - mrjink
1
然后我又读了一遍你的评论。是的,那就是我的意思,而且,那将会是一个更好的做法。 :) - mrjink
1
我刚想问有什么区别^^ 好的;) - Silly Freak
显示剩余2条评论

1
您不能在switch中使用String变量,但可以使用char。也许某个特定的char在所有字符串中都不同?
对于“someSubString”,“anotherSubString”和“yetanotherSubString”,您可以使用类似以下的内容:
switch(SomeString.chatAt(0)) {
    case 's':
    case 'a':
    case 'y':
}

但是这仅在您知道字符串的所有可能值并且特定位置的字符在所有值中都不同的情况下才有效。

1
应该使用charAt而不是chatAt。 - user2142786

0

对于相同类型的情况,我使用以下方法。

首先将所有要查找的字符串作为字符串获取:

String str ="someSubString,anotherSubString,yetanotherSubString"

然后从上述字符串中获取列表:

List items = Arrays.asList(str.split("\s*,\s*"));

现在循环上述列表并使用包含和开关语句。

<pre>
  for (String item : items) {
            if (mainStr.contains(item)) {
                switch (item) {
                    case "someSubString":
                        do something
                        break;
                    case "anotherSubString":
                        do something else
                        break;
                    case "yetanotherSubString":
                        do something even more different
                        break;
                }
            }
        }
</pre>

希望这能帮助那些正在寻找同类型需求的人们。

0
在Java 7中,您可以使用完整的字符串进行切换,但不能使用部分字符串。不过,您可以使用策略模式来处理这种情况。
private abstract class StringProcessor {
    String pattern;

    StringProcessor(String str) {
        pattern = str;
    }

    boolean matches(String str) {
        return str.matches(pattern);
    }

    abstract void process(String str);
}

StringProcessor[] processors = new StringProcessor[] {
    new StringProcessor("patt1") {
        void process(String str) {
            // do stuff for patt1
        }
    },
    new StringProcessor("patt2") {
        void process(String str) {
            // do stuff for patt2
        }
    }

};

然后在你的方法中:

for (StringProcessor sp: processors) {
    if (sp.matches(str)) {
        sp.process(str);
        break; // Don't break if you want the option to handle all that match
    }
}

现在,您可以添加任意数量的StringProcessors,并且它们都将被检查,如果有任何匹配,则会调用代码。在许多情况下,您可以预先定义处理器列表,但如果需要,也可以动态创建它。

显然,我更喜欢自己的方法^^ 对于严肃的情况,这可能是行得通的方式,但我不喜欢通过添加整个类(如果算上匿名类,我们有三个)来解决单一方法的问题(“我该如何编写这个switch?”。)就像枚举方法一样(使用常量特定的操作方法,这会导致相同数量的类),这还有一个额外的问题,即您不能使用原始方法的(非最终)局部变量。 - Silly Freak
原始方法中的变量可以传递到进程中(或者像你说的那样使其成为final)。switch结构本质上是脆弱的,一旦你有了超过几个选项,很容易失去对哪个case对应哪个选项的追踪。还要记住,在Java 8中,闭包也应该使得创建处理器的语法更加简洁。 - Tim B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接