替代 Java 中的 Switch Case
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1425659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Alternative to Switch Case in Java
提问by Biju CD
Is there any alternative way to implement a switch case in Java other than if else which is not looking good. A set of values will be there in combination, according to the selection corresponding method has to be executed.
除了看起来不太好的 if else 之外,是否还有其他方法可以在 Java 中实现 switch case。一组值将组合在一起,根据选择必须执行相应的方法。
采纳答案by ptomli
Presumably you're struggling with the requirement of case's being constant. Typically this is a code-smell, but there are things you can do. You might want to raise and link to another question that details why you're trying to switch.
据推测,您正在努力满足案例不变的要求。通常这是一种代码味道,但您可以做一些事情。您可能想提出并链接到另一个问题,详细说明您尝试转换的原因。
Map<String,Object> map = new HasMap<String,Object>();
// ... insert stuff into map
// eg: map.add("something", new MyObject());
String key = "something";
if (map.contains(key)) {
Object o = map.get(key);
}
In the example above, you might want to map to 'handlers', something like
在上面的示例中,您可能希望映射到“处理程序”,例如
interface Handler {
public void doSomething();
}
which then makes this all turn into a lookup.
然后这一切都变成了查找。
if (map.contains(key)) { map.get(key).doSomething(); }
Again, it's a bit of a smell, so please post a question which illustrates the reasoning.
同样,它有点味道,所以请发布一个说明推理的问题。
回答by Carlos Tasada
What do you want to do? Why is not Switch-Case good enough?
你想让我做什么?为什么 Switch-Case 不够好?
The fast answer is: use if-else
快速答案是:使用 if-else
回答by Carlos Tasada
if () {}
else if () {}
...
else if () {}
?
?
But I wouldn't say it is better...
但我不会说它更好......
回答by Pierre
a ugly series of if,else if,else
?
丑陋的系列if,else if,else
?
回答by Adam Batkin
How about an if
(along with else if
and else
) statement? While switch
will only allow you to switch using equality against integer or Enum types, if
lets you use any boolean logic.
一个if
(连同else if
和else
)语句怎么样?虽然switch
只允许您对整数或枚举类型使用相等进行切换,但if
允许您使用任何布尔逻辑。
回答by Taylor Leese
Refactoring your code to use polymorphism could get rid of the need for a switch statement. However, there are some legitimate uses for switch so it depends on your situation.
重构您的代码以使用多态可以摆脱对 switch 语句的需要。但是, switch 有一些合法用途,因此这取决于您的情况。
回答by sepp2k
You could always replace a switch with if-else if-else if-else if...
, though I don't see why you'd want to. Depending on the context switch
s can also sometimes be replaced by arrays or hashmaps.
你总是可以用 替换开关if-else if-else if-else if...
,但我不明白你为什么想要。根据上下文switch
s 有时也可以替换为数组或哈希图。
回答by OscarRyz
If you have plenty of switch/case statements around your code and they are driving you crazy.
如果您的代码周围有很多 switch/case 语句,并且它们让您发疯。
You could opt for the Refactoring: Replace conditional with polymorphism.
您可以选择重构:用多态替换条件。
Let's say you have a piece of software that is used to save information to different devices: 4 persistence operations are defined: fetch, save, delete, update, which could be implemented by N number of persistence mechanism ( flat files, network, RDBMS, XML, etc ) .
假设您有一个软件,用于将信息保存到不同的设备:定义了 4 个持久性操作:fetch、save、delete、update,可以通过 N 种持久性机制(平面文件、网络、RDBMS、 XML 等)。
Your code have to support them all so in 4 different places you have the this:
你的代码必须支持它们,所以在 4 个不同的地方你有这个:
BEFORE
前
class YourProblematicClass {
....
public void fetchData( Object criteria ) {
switch ( this.persitanceType ) {
case FilePersistance:
// open file
// read it
// find the criteria
// build the data
// close it.
break;
case NetWorkPersistance:
// Connect to the server
// Authenticate
// retrieve the data
// build the data
// close connection
break();
case DataBasePersistace:
// Get a jdbc connection
// create the query
// execute the query
// fetch and build data
// close connection
break;
}
return data;
}
Same for save/delete/update
保存/删除/更新相同
public void saveData( Object data) {
switch ( this.persitanceType ) {
case FilePersistance:
// open file, go to EOF, write etc.
break;
case NetWorkPersistance:
// Connect to the server
// Authenticate
// etc
break();
case DataBasePersistace:
// Get a jdbc connection, query, execute...
break;
}
}
And so on....
等等....
public void deleteData( Object data) {
switch ( this.persitanceType ) {
case FilePersistance:
break;
case NetWorkPersistance:
break();
case DataBasePersistace:
break;
}
}
public void updateData( Object data) {
switch ( this.persitanceType ) {
case FilePersistance:
break;
case NetWorkPersistance:
break();
case DataBasePersistace:
break;
}
}
Using switch/case statement becomes problematic:
使用 switch/case 语句会出现问题:
Each time you want to add a new type you have to insert new switch/case in each section.
Many times, some types are similar, and they don't need a different switch/case ( you could cascade them )
- Some other they are, and some times they differ slightly
- You may even need to load different type at runtime ( like plugins )
每次要添加新类型时,您都必须在每个部分插入新的开关/案例。
很多时候,某些类型是相似的,它们不需要不同的开关/外壳(您可以将它们级联)
- 他们是其他一些人,有时他们略有不同
- 你甚至可能需要在运行时加载不同的类型(比如插件)
So the refactoring here would be to add an interface or abstract type and have the different types implement that interface and delegate the responsibility to that object.
因此,这里的重构将是添加一个接口或抽象类型,并让不同的类型实现该接口并将责任委托给该对象。
So you would have something like this:
所以你会有这样的事情:
AFTER
后
public interface PersistenceManager {
public void fetchData( Object criteria );
public void saveData( Object toSave );
public void deleteData( Object toDelete );
public void updateData( Object toUpdate );
}
And different implementations
和不同的实现
public class FilePersistence implements PersistanceManager {
public void fetchData( Object criteria ) {
// open file
// read it
// find the criteria
// build the data
// close it.
}
public void saveData( Object toSave ) {
// open file, go to EOF etc.
}
public void deleteData( Object toDelete ){
....
}
public void updateData( Object toUpdate ){
....
}
}
And the other types would implement according to their logic. Network would deal with sockets, and streams, DB would deal with JDBC, ResultSets etc. XML with node etc.etc.
其他类型将根据其逻辑实现。网络将处理套接字和流,DB 将处理 JDBC、结果集等。 XML 与节点等。
public class NetworkPersistence implements PersistanceManager {
public void fetchData( Object criteria ) {
// Socket stuff
}
public void saveData( Object toSave ) {
// Socket stuff
}
public void deleteData( Object toDelete ){
// Socket stuff
}
public void updateData( Object toUpdate ){
// Socket stuff
}
}
public class DataBasePersistence implements PersistanceManager {
public void fetchData( Object criteria ) {
// JDBC stuff
}
public void saveData( Object toSave ) {
// JDBC stuff
}
public void deleteData( Object toDelete ){
// JDBC stuff
}
public void updateData( Object toUpdate ){
// JDBC stuff
}
}
And finally you just have to delegate the invocations.
最后你只需要委托调用。
Later:
之后:
public YouProblematicClass { // not longer that problematic
PersistamceManager persistance = // initialize with the right one.
public void fetchData( Object criteria ) {
// remove the switch and replace it with:
this.persistance.fetchData( criteria );
}
public void saveData( Object toSave ) {
// switch removed
this.persistance.saveData( toSave );
}
public void deleteData( Object toDelete ){
this.persistance.deleteData( toDelete );
}
public void updateData( Object toUpdate ){
this.persistance.updateData( toUpdate );
}
}
So, you just have to create the correct instance for the persistence manager according to the type only once. Then all the invocations are resolved by polymorphism. That's one of the key features of Object Oriented Technology.
因此,您只需要根据类型为持久性管理器创建正确的实例一次。然后所有的调用都通过多态来解决。这是面向对象技术的关键特性之一。
If you decide you need another persistence manager, you just create the new implementation and assigned to the class.
如果您决定需要另一个持久性管理器,您只需创建新的实现并分配给该类。
public WavePersistance implements PersistanceManager {
public void fetchData( Object criteria ) {
// ....
}
public void saveData( Object toSave ) {
// ....
}
public void deleteData( Object toDelete ){
// ....
}
public void updateData( Object toUpdate ){
// ....
}
}
回答by Pierre
or one could imagine a kind of dynamic switch case:
或者可以想象一种动态切换案例:
public interface Task<T>
{
public void doSomething(T context);
}
public Class SwitchCase<T>
{
Map<Integer,Task<T>> tasks;
Task<T> defaultTask;
public void choose(int choice, T context)
{
Task<T> t= this.tasks.get(choice);
if(t!=null) { t.doSomething(context); return;}
if(defaultTask!=null) { defaultTask.doSomething(context);}
}
}
回答by gia
I guess "Clean Code" has a nice chapter according switch/case vs. if/else.
我猜“干净的代码”根据 switch/case 与 if/else 有一个很好的章节。
Besides: I think it makes sense to decide whether you can reduce "noise" and make the code cleaner by using switch case, polymorphism or even a good ol' if/else. The number of cases plays a major role here, I guess.
此外:我认为决定是否可以通过使用 switch case、多态性或什至是一个好的 if/else 来减少“噪音”并使代码更简洁是有意义的。我想,案件数量在这里起着重要作用。