2012-11-11 85 views
1

所以我正在寫一個叫做getThanksgiving的方法。它按原樣工作,它是一個更大的班級的一部分,但我需要如何使其更有效的建議。 getWeekDay方法只是返回11月1日星期幾在用戶輸入年份。如何使此方法更高效?

public String getThanksgiving(){ 
String a = getWeekDay(11, 1); 
int offset = 0; 

    if(a.equals("Friday")){ 
    offset = 7; 
    } 

    if(a.equals("Saturday")){ 
    offset = 6; 
    } 

    if(a.equals("Sunday")){ 
    offset = 5; 
    } 

    if(a.equals("Monday")){ 
    offset = 4; 
    } 

    if(a.equals("Tuesday")){ 
    offset = 3; 
    } 

    if(a.equals("Wednesday")){ 
    offset = 2; 
    } 

    if(a.equals("Thursday")){ 
    offset = 1; 
    } 

int date = 21 + offset; 
thanksgiving = "Thursday, November " + date; 

return thanksgiving; 
} 

我試着將它重寫爲for循環,但它不工作。

public String getThanksgiving(){ 
String a = getWeekDay(11, 1); 
int offset = 8; 

String[] wTable = {"Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"}; 
    for(int i = 1; i < 8; i++){ 
     if(a.equals(wTable[i - 1])){ 
     offset --; 
     } 
    } 
} 

此外,抵消和添加21的想法正是我的老師希望我們做的事情。提前致謝!

+0

那麼,您允許使用哪些java構造?枚舉?地圖?或只有字符串,如果是和循環? – maasg

回答

1

可以使用開關罩

switch(a) 

{ 
    case "Monday": 
    offset = 4; 
    break; 

    case "Tuesday": 
    offset = 3; 
    break; 

} 

參考

switch(n) 
{ 
case 1: 
    execute code block 1 
    break; 
case 2: 
    execute code block 2 
    break; 
default: 
    code to be executed if n is different from case 1 and 2 
} 
+0

謝謝,但我還沒有真正瞭解開關盒。我會研究它! – user1816577

+0

@ user1816577您的歡迎 –

+0

@NullPointer我認爲開關子句中的字符串僅在Java 7中有效 – Serabe

0

我不認爲你可以把它 「更有效」(即運行時的性能)。如果你想使你的代碼 更具可讀性 短,我覺得你幾乎沒有

String[] wTable = {null, "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday", "Saturday", "Friday"}; 
for(int i = 1, n = wTable.lenght; i < n; i++) { 
    if(a.equals(wTable[i])){ 
     offset = i; 
     break; 
    } 
} 
0

要重點解決您的「如何使這種方法更有效」的問題,有一點要注意的是,方法即使在您已經找到您的解決方案的情況下也會對每個if語句進行評估。使用「裸露的骨頭」 java如果是,你可以添加一個條件來檢查的時候,天已經以這種方式被發現:

int offset = 0; 
boolean found = false; 
if(!found && a.equals("Friday")){ 
    offset = 7; 
    found = true; 
} 

if(!found && a.equals("Saturday")){ 
    offset = 6; 
    found = true; 
} 

此標誌將小幅憑藉&&(和)運營商的快捷評價減少運行時間,只執行字符串比較直到找到匹配。當您找到匹配的元素時,您可以使用for並使用break脫離循環來獲得類似的性能結果。

一個更好的選擇將被使用的地圖數據的結構:

Map<String, Integer> daysByOffset = new HashMap<String,Integer>(); 
// this 'setup' part you only do once 
daysByOffset.put("Friday", 7); 
daysByOffset.put("Saturday", 6); 
... 

然後查找部分是非常有效的,如在HashMap中的查找是O(1):

int offset = daysByOffset.get(day); 

的優雅的替代方案將使用封裝抵消信息的枚舉:

public enum DaysWithOffset { 
    FRIDAY(7), SATURDAY(6),..., THURSDAY(1); 
    private final offset; 
    private DaysWithOffset(int offset) { 
     this.offset = offset; 
    } 

    public int getOffset() { 
     return offset; 
    } 
} 

之後en嗯定義,每個枚舉常量將包含相應的偏移信息:

FRIDAY.getOffset() // = 7 

您可以計算通過解析根據提供的字符串枚舉,並要求從它的偏移值的偏移:

... 
String a = getWeekDay(11, 1); 
int offset = DaysWithOffset.valueOf(day.toUpperCase()).getOffset(); 
... 

即將回到關於哪個選項更高效的問題上,map和enum都有O(1)查找,(Enum查找通過優化的內部枚舉字典稍微好一些。然而,枚舉操作需要一個toUpperCase(),而映射不),這兩個選項都會比if(原始版本)或for循環的列表執行得更好。

我將這些選項包含在答案的完整性中,也可以讓您對Java語言提供的可能性進行「預測」。

現在一個傳情:如果你在斯卡拉這樣做,你會寫這樣的: val daysByOffset =地圖(「星期五」 - > 7,「星期六」 - > 6,...,「星期四「 - > 1) def thanksGiving(day:String):String =」November,November「+(daysByOffset(day)+21)

如果我今天正在學習一門語言,它應該是Scala。

0

這個怎麼樣?

private final static Map<String, int> dayMap = new HashMap<String,int>() 
{ 
dayMap.put("Monday", 0); 
// do for the rest 
}; 

in your method: 

public String getThanksgiving(){ 
    String a = getWeekDay(11, 1); 
    //do a lookup 
    int result = dayMap.get(a); 
    // do somthing with it. and return 
    return "blah "+ result; 
}