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

如何调用枚举方法与动态值在Java

庞鸿骞
2023-03-14

我正在开发一个程序,我必须找到机器人在网格中的位置,它可以向前移动,并且可以向北、南、东、西改变它的面,并且已经提供了给定的命令序列。那么,机器人的最终位置是什么。禁止使用任何类型的条件分支(例如if/more、开关/case)。

示例-
Grid-(100*500)
机器人的初始位置-(5,3)
可能的命令-
N-North,
E-East,
W-West,
S-South,
M-向前移动
示例输入-{N, S, M. M, E, W, E, S, M, S, M}

我尝试使用Enum,但我面临的问题是如何使用我使用命令获得的动态值调用Enum方法。

public class RobotMovesInGrid {
    Scanner input = new Scanner(System.in);
    String command=input.next();
    int commLength = command.length();

    static enum Command {
        N{@Override public void execute(String g, String r){ System.out.println("do the N move here"); }},
        E{@Override public void execute(String g, String r){ System.out.println("do the E move here"); }},
        S{@Override public void execute(String g, String r){ System.out.println("do the S move here"); }},
        W{@Override public void execute(String g, String r){ System.out.println("do the W move here"); }},
        M{@Override public void execute(String g, String r){ System.out.println("do the M move here"); }};
        public abstract void execute(String g, String r);

    }
    public void nextPosition() {
        Command c1;
        for(int i=0;i<commLength;i++) {
            if (command.charAt(i)=='N'||command.charAt(i)=='E'|| command.charAt(i)=='S'|| command.charAt(i)=='W'||command.charAt(i)=='M')

                c1= Command.M;// Here instead of M, I am trying to give dynamic commands but it is not taking it
            System.out.println("Current position is"+c1);
        }
    }
}

有人可以建议我如何使用作为输入的命令调用枚举方法吗。

共有3个答案

伍宝
2023-03-14

最简单的方法是将char输入转换为字符串,然后调用枚举的valueOf(String)方法来检索枚举,例如:

for(int i=0;i<commLength;i++) {
   Command command = Command.valueOf(String.valueOf(command.charAt(i))
                                           .toUpperCase());
   if (command != null){
       command.execute(...);
   }
}

它会起作用,但我认为您的枚举值的名称实际上毫无意义
您应该根据其含义重命名它们,使用包含映射字符的构造函数丰富枚举类,并引入静态方法来检索与输入字符关联的枚举值:

static enum Command {
    NORTH('N'){@Override public void execute(String g, String r){ System.out.println("do the N move here"); }},
    EAST('E'){@Override public void execute(String g, String r){ System.out.println("do the E move here"); }},
    SOUTH('S'){@Override public void execute(String g, String r){ System.out.println("do the S move here"); }},
    WEST('W'){@Override public void execute(String g, String r){ System.out.println("do the W move here"); }},
    MOVE_FORWARD('M'){@Override public void execute(String g, String r){ System.out.println("do the M move here"); }};

    private char mappingChar;

    Command (char mappingChar){
        this.mappingChar = mappingChar;
    }

    public abstract void execute(String g, String r);

    public static Optional<Command> getFrom(char mappingChar) {
        for (Command command : values()) {
            if (Character.toUpperCase(mappingChar)==command.mappingChar) {
                return Optional.of(command);
            }
        }
        return Optional.empty();
    }
}

现在可以动态检索枚举值并使用它:

for(int i=0;i<commLength;i++) {
    Optional<Command> optCommand = Command.getFrom(command.charAt(i)); 
    if (optCommand.isPresent()){
        optCommand.get().execute(...)
    }

    // or alternatively 
    optCommand.ifPresent(c -> c.execute(...));        
}
彭弘方
2023-03-14

一种方法是在内部类的枚举命令中使用一个常量静态映射;它将字符串关联到命令<代码>命令。parse在映射中查找命令。

import java.lang.String;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.function.Function;
import java.awt.Point;
import java.util.Scanner;

class Robot {

    public static void main(String args[]) {
        try(Scanner input = new Scanner(System.in)) {
            input.useDelimiter(",\\s*|\n");
            Robot r = new Robot();
            while(input.hasNext()) {
                try {
                    Command.parse(input.next().trim()).apply(r);
                } catch(NullPointerException e) {
                    System.out.printf("Syntax error.\n");
                } catch(RuntimeException e) {
                    System.out.printf("Can't go that way: %s.\n",
                        e.getMessage());
                }
            }
        } catch(Exception e) {
            System.err.printf("%s: %s.\n", e, e.getMessage());
        }
    }

    Point x;
    static Point dim;
    Command last;

    Robot() {
        dim = new Point(100, 500);
        x = new Point(5, 3);
    }

    enum Command {
        N("N", "north",  true,  (r) -> new Point(r.x.x, r.x.y - 1)),
        E("E", "east",   true,  (r) -> new Point(r.x.x + 1, r.x.y)),
        S("S", "south",  true,  (r) -> new Point(r.x.x, r.x.y + 1)),
        W("W", "west",   true,  (r) -> new Point(r.x.x - 1, r.x.y)),
        M("M", "farther",false, (r) -> r.last != null ?r.last.go.apply(r):null);

        private String command, name;
        private boolean isDir;
        private Function<Robot, Point> go;
        private static final Map<String, Command> map;

        /* Map for turning commands into Directions; mod->const map. */
        static {
            Map<String, Command> mod = new HashMap<>();
            for(Command c : values()) mod.put(c.command, c);
            map = Collections.unmodifiableMap(mod);
        }

        /** Called from definition of enum. */
        private Command(final String command, final String name, boolean isDir,
            final Function<Robot, Point> go) {
            this.command = command;
            this.name    = name;
            this.isDir   = isDir;
            this.go      = go;
        }

        /** @param str A string representing the direction.
         @return The command or null. */
        public static Command parse(final String str) { return map.get(str); }

        /** Applies this command to r. */
        public void apply(Robot r) {
            Point x = this.go.apply(r);
            if(x == null)
                throw new RuntimeException("don't have a direction");
            if(x.x < 0 || x.x >= dim.x || x.y < 0 || x.y >= dim.y)
                throw new RuntimeException("at the edge");
            r.x = x;
            if(this.isDir == true) r.last = this;
            System.out.printf("Went %s to (%d, %d).\n", r.last.name, x.x, x.y);
        }

        /** @return The name of the direction. */
        public String toString() { return name; }
    }

}

它在EOF结束。我发现这些很有用,

  • https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
蒋烨然
2023-03-14

这是另一个解决方案。

    static enum Command {
        N(-1,0),E(0,1),W(0,-1),S(1,0);
        private int rowIncrement;
        private int colIncrement;

        private Command(int rowIncrement, int colIncrement)
        {
            this.rowIncrement = rowIncrement;
            this.colIncrement = colIncrement;
        }

        public int getRowIncrement()
        {
            return rowIncrement;
        }

        public int getColIncrement()
        {
            return colIncrement;
        }
    }

这是命令评估的代码。

    //input
    String command = "NSMMEWESMSM";
    int[] pos = new int[]{5,3};
    int[] size = new int[]{100, 500};

    char[] chars = command.toCharArray();
    //replace M by the previous char, ie move in the same direction
    for (int i = 0; i < chars.length; i++)
    {
        char dir = chars[i];
        //this assumes that M cannot be the first char
        if (dir == 'M')
        {
            dir = chars[i-1];
            chars[i] = dir;
        }
    }


    for (char dir : chars)
    {
        Command cmd = Command.valueOf(String.valueOf(dir));
        pos[0] += cmd.rowIncrement;
        //row is within the region
        pos[0] = Math.min(Math.max(pos[0], 0), size[0] -1);

        pos[1] += cmd.colIncrement;
        //col is within the region
        pos[1] = Math.min(Math.max(pos[1], 0), size[1] -1);
    }
 类似资料:
  • 问题内容: 4年前关闭。 刚刚下载了Xcode 7 Beta,并列举了此错误 错误: 枚举不可用在序列上调用枚举方法 问题答案: 在Swift 2中,它不再是全局函数,而是的扩展。 直接在序列上调用它以进行枚举,如下所示:

  • 问题内容: Java中的静态和非静态枚举有什么区别?两种用法是相同的。 正确吗 所有静态的都在启动时加载到内存中,非静态的则按需加载 ? 如果是,那么哪种方法更好?将某些数据始终保留在内存中还是每次使用服务器资源加载它们? 问题答案: 所有的都是有效的。如果您有嵌套的枚举,则它与相同。 所有类都是延迟加载的(枚举或其他),但是在加载时,它们会一次全部加载。也就是说,您不能加载一些常量,而不能加载其

  • 多次调用特定枚举类的value()函数是否效率低下? 我见过一些现有代码的实例,其中values()的结果被缓存以供重用。这有用吗?

  • 问题内容: 我想知道在Java中是否可以嵌套枚举。 在这里,我想做的是: 拥有一个由CAT和DOG组成的物种,将允许我访问可用CAT和DOG品种的子枚举。例如,我希望能够测试是否装有CAT或DOG,以及动物是否是PERSAN CAT或PITBULL狗。CAT和DOG品种必须是不同的枚举,即CatBreeds枚举和DogBreeds枚举。 这是我要使用的访问模式的示例: 种类: 物种 种狗 品种:

  • 问题内容: 我无法使用从常量中获取的枚举作为注释中的参数。我收到此编译错误:“注释属性[attribute]的值必须是枚举常量表达式”。 这是枚举代码的简化版本: 对于注释: 和班级: 该错误仅在方法B的“ theEnum = MYENUM_CONSTANT”中显示。字符串和int常量对于编译器是可以的,但Enum常量不是,即使它的值与methodA上的值完全相同。在我看来,这是编译器中缺少的功能

  • 问题内容: 假设我有一个格式为基本XML的文件,如下所示: 我想在运行时变成这样的东西: …,然后将新创建的枚举传递给我的应用程序。我将如何实现这样的目标?可以吗 问题答案: 您尝试做的事情没有任何意义。枚举实际上仅是为了编译时的利益,因为它们表示一组固定的常量。在运行时,动态生成的枚举的含义是什么- 与普通对象有什么不同?例如: 您的XML可以解析为新实例化的对象,这些对象可以存储在某些程序中,