简体   繁体   English

如何使这种方法更有效?

[英]How to make this method more efficient?

So I'm writing a method called getThanksgiving . 所以我正在写一个叫做getThanksgiving的方法。 It works as is and it's part of a much larger class but I needed advice on how to make it more efficient. 它按原样工作,并且是更大的类的一部分,但是我需要如何提高效率的建议。 The getWeekDay method just returns what day of the week November 1 is on a user-inputted year. 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;
}

I tried rewriting it as a for loop but it's not working. 我尝试将其重写为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 --; 
        }
    }
 }

Also, the idea of offset and adding 21 is just something my teacher wants us to do. 另外,偏移和加21的想法只是我的老师希望我们做的。 Thanks in advance! 提前致谢!

you can use switch case 你可以用开关盒

like 喜欢

switch(a )

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

  case "Tuesday":
    offset = 3;
    break;

}

reference 参考

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
}

I don't think you can make it "more efficient" (ie runtime performance). 我认为您无法使其“更加高效”(即运行时性能)。 If you want to make your code more readable shorter, I think you're almost there 如果您想使代码的 可读性 更短,我想您就快到了

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; 
    }
}

To specifically address your question on 'how to make this method more efficient', one thing to note is that the method evaluates every if statement even in the case when you already found your solution. 为了专门解决有关“如何使这种方法更有效”的问题,需要注意的一件事是,即使已经找到了解决方案,该方法也会评估每个if语句。 Using 'bare bones' java if's you could add a condition to check when the day has been found in this way: 使用'bare bones'java if's,可以添加条件来检查何时以这种方式找到日期:

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

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

This flag will marginally reduce runtime by virtue of shortcut evaluation of the && (and) operator, only executing the string comparison until a match is found. 该标志将通过&& (和)运算符的快捷方式评估来略微减少运行时间,仅执行字符串比较,直到找到匹配项为止。 You can achieve a similar performance result with a for and using break to get out of the loop when you have found a matching element. 当找到匹配的元素时,可以使用for并使用break来实现循环,从而获得相似的性能结果。

A better alternative would be using a Map data structure: 更好的选择是使用Map数据结构:

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

Then the lookup part is very efficient, as the lookup in a hashmap is O(1): 然后,查找部分非常有效,因为哈希图中的查找为O(1):

int offset = daysByOffset.get(day);

An elegant alternative would be using enums that encapsulate the offset information: 一个很好的选择是使用封装偏移信息的枚举:

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

    public int getOffset() {
        return offset;
    }
}

After the enum is defined, each enum constant will contain the corresponding offset info: 定义枚举后,每个枚举常量将包含相应的偏移量信息:

FRIDAY.getOffset() // = 7

You can calculate the offset by resolving the enum from the provided String and asking the offset value from it: 您可以通过从提供的String中解析枚举并从中查询偏移值来计算偏移量:

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

Coming back to the question on which option is more efficient, both map and enum have an O(1) lookup, (the Enum lookup being slightly better by the optimized internal enum dictionary. Yet, the enum operation requires a toUpperCase(), while the map doesn't) both these options will perform a lot better than a list of if's (the original version) or a for loop. 回到哪个选项更有效的问题,map和enum都具有O(1)查找(通过优化的内部enum字典,Enum查找会稍微好一些。但是,enum操作需要toUpperCase(),而地图没有)这两个选项的性能要比if(原始版本)或for循环列表好得多。

I include these options for completeness of the answer and also for you to have a 'sneak preview' of the possibilities that the Java language offers. 我提供了这些选项,以确保答案的完整性,并让您“偷窥” Java语言提供的可能性。

Now a teaser: If you were doing this in Scala, you'd write something like this: val daysByOffset = Map("Friday" -> 7, "Saturday" -> 6,...,"Thursday" ->1) def thanksGiving(day:String):String = "Thursday, November " + (daysByOffset(day)+21) 现在是一个预告片:如果您在Scala中进行此操作,则需要编写如下代码:val daysByOffset = Map(“ Friday”-> 7,“ Saturday”-> 6,...,“ Thursday”-> 1) def ThanksGiving(day:String):String =“十一月星期四” +(daysByOffset(day)+21)

If I were learning a language today, it would be Scala. 如果我今天正在学习一门语言,那就应该是Scala。

how about this? 这个怎么样?

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM