java if emun_关于java:Enum与If-else
我有一個需求,其中我需要從事件列表中構建如下的雇員對象。 目前,我的代碼如下所示,但是QE發表評論說可能使用枚舉而不是多個。
有人可以建議我如何用枚舉實現這一點。
Employee e= new Employee();
for(Event event:events){
if("empid".equals(event.getName())
e.setEmployeeId(event.getvalue());
else if("empname".equals(event.getName())
e.setEmployeeName(event.getvalue());
else if("empsal".equals(event.getName())
e.setEmployeeSal(event.getvalue());
else if("empdob".equals(event.getName())
e.setEmployeeDOB(event.getvalue());
else if("emprole".equals(event.getName())
e.setEmployeeRole(event.getvalue());
}
雅。 根據事件名稱為empname,empsal等和switch創建一個枚舉(假設您使用的是Java 7+)。 刪除雜亂的if-else子句,由于不掃描所有情況,切換速度更快
您好Vinod感謝您的快速回復。 您可以張貼關于如何執行此操作的示例代碼片段嗎?還有,我使用Java 6而不是7
檢查這個問題
您可以在同一示例上查看以下答案。
如果您控制Event的開發,我相信您的QE所說的是用enum替換事件名稱(這是明智的設計,因為您已經確定了事件的可能類型)。但是,如果Event的設計超出了您的控制范圍,或者您不能使用Event的子類供您使用(例如制作一個EmployeeEvent),那么請忽略我要說的內容)
即
enum EventType {
EMP_ID,
EMP_NAME,
....
}
interface Event {
EventType getType(); ? // instead of getName() which returns a String
}
然后您的代碼可以簡化為
Employee e= new Employee();
for (Event event: events) {
switch (event.getType()) {
case EMP_ID:
e.setEmployeeId(event.getvalue());
break;
case EMP_NAME:
e.setEmployeeName(event.getvalue());
break;
....
}
}
您甚至可以使用地圖來預設針對每種事件類型執行的操作(這與另一個答案的想法類似)
Map> eventActions = new EnumMap<>();
eventActions.put(EventType.EMPLOYEE_ID, Employee::setEmployeeID);
eventActions.put(EventType.EMPLOYEE_NAME, Employee::setEmployeeName);
因此您可以通過以下方式進一步簡化上述開關:
Employee e= new Employee();
for (Event event: events) {
eventActions.get(event.getType()).accept(e, event.getValue()));
}
我建議您將處理事件的邏輯移到enum中。如果您使用的是Java 8,則它將類似于:
enum EmployeeField {
ID("empid", Employee::setEmployeeID),
NAME("empname", Employee::setEmployeeName),
SALARY("empsalary", Employee::setEmployeeSalary),
...
private final String key;
private final BiConsumer valueSetter;
EmployeeField(String key, BiConsumer valueSetter) {
this.key = key;
this.valueSetter = valueSetter;
}
public void setEmployeeField(Employee employee, String value) {
valueSetter.accept(employee, value);
}
public static EmployeeField getFieldForKey(String key) {
return Arrays.stream(values[])
.filter(ef -> ef.key.equals(key))
.findAny()
.orElseThrow(new IllegalArgumentException("No employee field" + key));
}
}
然后,您可以完全省去switch語句,而只需使用:
events.stream()
.forEach(ev -> EmployeeField.getFieldForKey(ev.getName())
.setEmployeeField(emp, ev.getValue()));
這也意味著有關雇員字段的所有信息(包括如何設置雇員值)都封裝在枚舉中,并且可以輕松更改或擴展而不會影響其他任何內容。
請注意,您可以在不使用lambda的情況下在Java 8之前執行類似的操作,但是(在我看來)它并不那么優雅,因為匿名接口實例需要顯式化,這會使代碼復雜得多。或者,您可以為每個枚舉成員重寫方法(在我看來),這些方法甚至更丑陋。
有關Java 8之前的版本的信息,請參見stackoverflow.com/questions/7413872 /(setEmployeeField是抽象方法)
@RC那就是我在上一段中提到的方法。我懷疑我們所有人都認為Java 8整潔了很多!
我只是評論鏈接以說明目的;)
@RC謝謝。很多人似乎仍然是Java 8之前的人。現在,我曾經習慣于lambda和流,我無法想象沒有它們:-)
盡管該解決方案有效,但是如果您再看一眼,在這里使用enum幾乎毫無意義。您僅有的"優勢"只是訪問values以獲得可用的"字段"列表,對此您實際上并不需要enum。
@AdrianShum我不確定我是否完全理解您的觀點。使用枚舉的唯一原因是擁有一組預定義的值。這幾乎是所有枚舉所要做的。您總是可以使用帶有一組靜態字段的類來代替,但是枚舉更整潔。您能否進一步解釋一下關于枚舉在這里毫無意義的觀點?
問題實際上是您沒有將枚舉本身用作預定義的值集。您只是使用它來保存字符串值。也許是這樣:即使您將枚舉值重命名為無意義的東西(E1,E2 ...),也不會對程序造成任何影響。您試圖實現的只是從字符串到要調用的方法的映射。您只需制作一張地圖即可。使用Map實際上更好,因為每次嘗試查找要調用的方法時實際上都在進行順序搜索,而使用Map則效率更高
使用以下代碼創建一個枚舉
public enum ?EMPLOYEE_FIELDS {EMPID, EMPNAME,EMPSAL, EMPDOB, EMPROLE};
EMPLOYEE_FIELDS empField = EMPLOYEE_FIELDS.valueOf(event.getName().toUpperCase());
switch(empField ){
case EMPID:
//do something here
break;
case EMPNAME:
//do something here
break;
// other cases.
// other cases.
// other cases.
default:
//do something here
}
希望這可以幫助!
這將如何工作?字符串" empname"," empsal"等應映射在枚舉中。
請發布正確的答案-如果您需要枚舉為EMPNAME和EMPSAL才能使代碼正常工作,然后以這種方式在答案中做出選擇!
枚舉中所做的更改以匹配問題字符串
@barakmanos這個問題要求使用字符串和枚舉來替代多號。我已經嘗試在此解決方案中使用枚舉。
eeek。我真的不喜歡覆蓋枚舉名稱以匹配事件鍵的樣式。那是一個非常脆弱的方法(我認為)。最好在枚舉中包含鍵。
總結
以上是生活随笔為你收集整理的java if emun_关于java:Enum与If-else的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么格式化电脑_U盘格式化后数据能恢复吗
- 下一篇: 将你一张表的值覆盖_精准度可达亚米级,山