首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何简化庞大的switch-case表达式?

如何简化庞大的switch-case表达式?
EN

Stack Overflow用户
提问于 2020-08-27 20:22:36
回答 2查看 61关注 0票数 0

我遇到了一些关于next代码的问题。我有一个简单的界面,比如:

代码语言:javascript
复制
public interface Game {
    int start();
}

许多实现此接口的类如下所示:

代码语言:javascript
复制
public class FirstGame implements Game {
    public static final int ID = 1;
    
    @Override
    int start() {
        // Do something and return result
    }
}

以及具有如下方法的GameManager类:

代码语言:javascript
复制
public Game getGameById(int id) {
    switch(id) {
        case FirstGame.ID:
            return new FirstGame();
        case SecondGame.ID:
            return new SecondGame();
        // ..... and many other cases....
    }
    return null;
}

我试图使用如下的反射来简化这个switch-case结构:注解:

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface GameId {

long value() default 0;
}

FirstGame类:

代码语言:javascript
复制
@GameId(value = 1)
public class FirstGame implements Game {
    public static final int ID = 1;
    
    @Override
    int start() {
        // Do something and return result
    }
}

和如下的GameManager方法:

代码语言:javascript
复制
public Game getGameById(int id) {
    Game game = null;
    try {
        Reflections reflections = new Reflections();
        for (Class<?> clazz : reflections.getTypesAnnotatedWith(GameId.class)) {
            if (clazz.getAnnotation(GameId.class).value() == id) {
                Constructor constructor = clazz.getConstructor();
                game = (Game) constructor.newInstance();
                break;
            }
        }
    } catch (Exception ex) { ex.printStackTrace();}
    return game;
}

但它的效果太慢了。那么,如何以其他方式简化switch-case表达式呢?感谢并为我糟糕的英语表达歉意。

EN

回答 2

Stack Overflow用户

发布于 2020-08-27 20:49:29

这个怎么样?

代码语言:javascript
复制
static final List<Supplier<Game>> GAMES = List.of(
    FirstGame::new,
    SecondGame::new
    // ...
);

public Game getGameById(int id) {
    return GAMES.get(id).get();
}

代码语言:javascript
复制
static final Map<Integer, Supplier<Game>> GAMES = Map.of(
    1, FirstGame::new,
    2, SecondGame::new
);

public Game getGameById(int id) {
    return GAMES.get(id).get();
}
票数 1
EN

Stack Overflow用户

发布于 2020-08-27 21:52:11

感谢Holger的回答。我的反射方法非常接近成功。它只需要将所有构造函数添加到HashMap中一次,其中ID用作键。所以现在我的GameManager代码看起来像这样:

代码语言:javascript
复制
Map<Integer, Constructor> constructorMap = new HashMap<>();

private void fillConstructorMap() {
    try {
        ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
        configurationBuilder.addUrls(ClasspathHelper.forPackage("com.my.package.name"));
        Reflections reflections = new Reflections(configurationBuilder);
        for (Class<?> clazz : reflections.getTypesAnnotatedWith(GameId.class)) {
            Integer id = clazz.getAnnotation(GameId.class).value();
            Constructor constructor = clazz.getConstructor();
            constructorMap.put(id, constructor);
        }
    } catch (NoSuchMethodException ex) {
        ex.printStackTrace();
    }
}

public Game getGameById(int id) {
    Game game = null;
    try {
        game = (Game) constructorMap.get(id).newInstance();
    } catch (Exception ex) {ex.printStackTrace();}
    return game;
}

此方法与使用switch-case表达式的方法一样快。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63615912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档