当前位置: 首页 > 知识库问答 >
问题:

如何确保开关/大小写语句具有所有选项,例如使用枚举?

樊奇思
2023-03-14

我想在Java中创建一个开关/大小写语句,并确保所有字符串都在语句中。

然而,在Java中使用简单的字符串(即北、南、东、西)创建枚举很容易。

对于带点和空格的字符串会怎么做?即“这是描述”,“com.stackoverflow.ClassName”

共有2个答案

裴兴言
2023-03-14

如果您询问是否可以创建常量有空格的枚举,那么答案是“否”。

枚举常量是普通Java标识符,如类或变量名,因此它们中不能有空格或特殊字符。

然而,将枚举与字符串链接是不可能的吗?否。<br>如果出于某种原因,您希望您的开关大小写使用<code>枚举</code>以提高可读性/简洁性,但您的输入是<code>字符串

您需要扩展枚举以拥有一个额外的字段(我们称之为标签)来保存这个字符串
在使用<code>enum方法<br>返回对应于提供<code>字符串的<code>枚举。

下面是一个小示例类,它使用枚举值北、东、南、西、
链接到不同(无效枚举命名)结构的字符串

public class EnumExample {

    enum SwitchEnum {
        NORTH   ("North star"),
        EAST    ("Eastpack rulez!"),
        SOUTH   ("https://www.southafrica.net/"),
        WEST    ("java.awt.BorderLayout.WEST");

        private final String label;
        SwitchEnum(final String label) {
            this.label = label;
        }

        @Override
        public String toString() {
            return this.label;
        }

        private static final Map<String,SwitchEnum> map;
        static {
            map = new HashMap<String,SwitchEnum>();
            for (SwitchEnum v : SwitchEnum.values()) {
                map.put(v.label, v);
            }
        }
        public static SwitchEnum findByLabel(String label) {
            return map.get(label);
        }
    }

    public static String doEnumSwitch(String enumString) {
        SwitchEnum enm = SwitchEnum.findByLabel(enumString);
        if (enm != null) {
            String enumReturn = enm.name() +" : "+ enm;
            switch (enm) {
                case NORTH:
                    return enumReturn +" - Up there.";
                case EAST:
                    return enumReturn +" - Now for sale.";
                case SOUTH:
                    return enumReturn +" - Now with 50% more elephants.";
                default:
                    return "UNHANDLED ENUM : "+ enm.name() +" - "+ enm;
            }
        } else {
            return "UNKNOWN ENUM : "+ enumString;
        }
    }

    public static void main(String[] args) {
        System.out.println(doEnumSwitch("North star"));
        System.out.println(doEnumSwitch("Eastpack rulez!"));
        System.out.println(doEnumSwitch("https://www.southafrica.net/"));
        System.out.println(doEnumSwitch("java.awt.BorderLayout.WEST"));
        System.out.println(doEnumSwitch("I only want to get out of here."));
    }
}

这将输出以下内容

北:北极星 - 在那里。
东 : 东包规则! - 现在出售。
南部:https://www.southafrica.net/ - 现在大象增加了50%。
未经处理的枚举:西部 - 爪哇.awt.边界布局,西部
未知枚举:我只想离开这里。

步胜
2023-03-14

我认为这个问题的主要问题是,IDE告诉您switch语句中缺少枚举值。并询问您是否要添加它们而不是编译器。当然,这并不能确保枚举类的用户必须使用每个值。

Joshua Bloch在他的有效Java书(第章使用接口模拟可扩展枚举,可以更改该接口以使用此处显示的交换机:Java枚举交换机。但是我认为交换机解决方案并没有提供使用所有枚举的完全安全性。

但是,由于您想知道是否存在使用字符串的解决方案,因此我们还可以尝试使用如下所示的函数式方法:枚举切换函数式方法,并使其与字符串字段而不是枚举一起使用。

这可能如下所示:

public class Direction {
    private static final String NORTH = "north";
    private static final String SOUTH = "south";
    private static final String EAST = "east";
    private static final String WEST = "west";

    public interface SwitchResult {
        void NORTH();
        void SOUTH();
        void EAST();
        void WEST();
    }

    public static void switchValue(String direction, SwitchResult result){
        switch (direction){
            case NORTH:
                result.NORTH();
                break;
            case SOUTH:
                result.SOUTH();
                break;
            case EAST:
                result.EAST();
                break;
            case WEST:
                result.WEST();
                break;
        }
    }

    public static void main(String[] args) {
        String direction = "west";
        Direction.switchValue(direction, new SwitchResult() {
            @Override public void NORTH() {
                System.out.println("this time north");
            }

            @Override public void SOUTH() {
                System.out.println("this time south");
            }

            @Override public void EAST() {
                System.out.println("this time east");
            }

            @Override public void WEST() {
                System.out.println("this time west");
            }
        });
    }
}

正如您在main方法中看到的,如果您想调用SwitchValue函数,您必须传递您的字符串和接口的实现,这可以确保您覆盖所有可能性。作为交换,代码是非常冗余的。如果您只有对提供一堆String值的类的读取权限并且您想围绕它构建一个开关语句,则可以使用这种方法。在其他任何地方,您都应该真正坚持使用枚举的方法。

如果您想使用第三方工具来真正确保无需编写任何多余的样板代码,请看一下:

    < Li > FindBugs SF _ SWITCH _ NO _ DEFAULT:但这只包括SWITCH语句的默认分支。 < Li > @ enum mapper:Annotation processor,它在编译时检查是否处理了所有枚举常量
 类似资料:
  • 我正在尝试检查我的VO中设置了哪些值。 下面是我的女儿。我得到的是“合格的病例标签MyEnum.UserType.Doctors必须替换为不合格的枚举常量Doctors” EnumTest.java

  • 我只是在Java中测试一些并发编程。基本上,我有一个类(Light),它是一种有限状态机,并根据命令改变其状态。这就是我正在尝试的:灯处于开启状态,我向这个类的线程发送一个命令来改变关闭状态。但是我在执行过程中遇到了一个问题。 首先,让我向大家介绍一下: 输出显示我处于ON状态,而我应该处于OFF状态。 在第二次运行时,在放入一条指令(< code>System.out.println或其他指令后

  • 我已经开始与其他人一起研究VS代码,他们使用的标签大小为4,而我使用的是2。我现在也将我的改为4,但我已经编写的代码标签大小为2,但我想将其全部改为4而无需手动遍历所有代码。 有没有简单的方法可以做到这一点?

  • 问题内容: 有人可以解释一下为什么我的循环从0变为7吗?我只需要获得前3种情况,但是程序将遍历所有代码。代码位于show()方法中。 问题答案: 因为没有休息。在每种情况下,您都需要break关键字。有关详细说明,请参见switch语句Java教程。 例如 否则,如果上述情况之一被评估为true,则将执行其他情况。

  • 我正在制作一个简单的石头剪刀程序,但不确定如何确保用户只输入有效的选项。如果他们不键入“石头”、“纸”或“剪刀”(大写不重要)等变量,然后再键入“是”或“否”,我需要能够对他们进行谴责。建议? }

  • 我有几个switch语句测试。所有<code>enumenum可能会收缩和增长。当<code>枚举 已经存在“如何检测新值已添加到枚举中并且未在开关中处理”的问题,但它不包含答案,而只是与Eclipse相关的工作。