【问题标题】:Is there any code I could write that is more effective and clean rather than a bunch of else if statements?有没有比一堆 else if 语句更有效和更简洁的代码?
【发布时间】:2021-04-21 20:17:01
【问题描述】:

我更像是一个中级 android 开发者,我想学习如何编写更简洁有效的代码,我在我的应用程序上遇到了这个问题,需要检查一堆语句,比如变量是否为对于每个单独的评分,都小于或大于。

private void rateStock(double peRatio) {
    //For Dividend Stocks
    if(currentDiv != 0 && fiveYearDiv != 0){
        double dividendDiff = currentDiv - fiveYearDiv;
        if (peRatio <= 20 && peRatio > 0  && dividendDiff >= 0.01 && payoutRatio <= 0.65) {
            int stockRatingDividend = 5;
            addItems(stockRatingDividend);
        } else if (peRatio > 20 && peRatio <= 25 && dividendDiff >= 0.005 && payoutRatio <= 0.75) {
            int stockRatingDividend = 4;
            addItems(stockRatingDividend);
        } else if (peRatio > 25 && peRatio <= 30 && dividendDiff >= 0.001 && payoutRatio <= 0.85) {
            int stockRatingDividend = 3;
            addItems(stockRatingDividend);
        } else if (peRatio > 30 && peRatio <= 35 && payoutRatio <= 0.95) {
            int stockRatingDividend = 3;
            addItems(stockRatingDividend);
        } else if( peRatio > 35 &&  peRatio <= 40 && currentDiv > fiveYearDiv && payoutRatio >= 100) {
            int stockRatingDividend = 2;
            addItems(stockRatingDividend);
        } else if( peRatio > 40 || peRatio < 0 && fiveYearDiv > currentDiv  && payoutRatio >= 100) {
            int stockRatingDividend = 1;
            addItems(stockRatingDividend);
        } else {
            int stockRatingDividend = 0;
            addItems(stockRatingDividend);
        }
    }
}

从上面的代码可以看出,它非常混乱,甚至无法正常工作,因为它必须检查的条件太多,而且它通常不适合任何 else if 语句,只返回 0

我知道这可能很多,但至少有人可以指导我写一篇关于如何编写更有效和更简洁的代码而不是为这段代码编写混乱的 else if 语句的帖子吗?

【问题讨论】:

  • addItems(stockRatingDividend);只能在最后一个else之后写入一次
  • @fantaghirocco 谢谢!这是一个我忽略的好主意,但是如果检查混乱,那么整个其他的呢,你知道我可以在那里改变什么吗?
  • 在开头声明int stockRatingDividend = 0;,在结尾声明addItems(stockRatingDividend);,不带子句,只声明一次。没有这么多重复,它会以相同的方式运行

标签: java performance android-studio if-statement conditional-statements


【解决方案1】:

对于任何有同样问题的未来流浪者,我自己想出了一个解决方案!

我所做的是将它分成不同的类,并在第一类 ValueLists.java 我创建了所有范围并为列表创建了一个 getter。

public List<Range> getPeRatioRanges() {

        Range range20 = new Range(0, 20);
        Range range25 = new Range(21, 25);
        Range range30 = new Range(26, 30);
        Range range35 = new Range(31, 35);
        Range range40 = new Range(36, 40);

        List<Range> list = new LinkedList<>(Arrays.asList(range40, range35, range30, range25, range20)); // add in reverse order cuz index = rating

        return list;
    }

在另一个类 CheckRatingOfStock.java 中,我创建了一个简单的循环,用于遍历范围并获得评级。

 List<Range> peRatioRanges = getPeRatioRanges();

            for (int i = 0; i < peRatioRanges.size(); i++) {
                Range range = peRatioRanges.get(i);
                int intPERatio = (int) rawPEratio;

                if (range.contains(intPERatio)) {
                    rating = i + 1;
                }
            }

这里范围的索引是评级 + 1,所以如果它的 0-20 是评级 5,因为列表是相反的。 这样使用 2 块代码,我避免了很多来回和大量 else if 语句的混乱,并且至少在我看来,它更易于维护和清洁。

这可以作为一个方法来实现:

static int getIndexOfRange(int intPERatio, List<Range> ranges)
{
    for (int i=0; i< ranges.size(); i++) 
       if (ranges.get(i).contains(intPERatio)) 
           return i+1;                         //if found, return immediatelly
              
    return -1;   //if it reaches this line, means the item was not found
 }               //return -1 as representation of this
 

【讨论】:

  • 它可以,但它不仅适用于这一件事,它还适用于检查其他 5 件事,因此将其设为 1 类比 5 种不同的方法更干净,因为我后来所做的是将它们放在一起获得 1 分
【解决方案2】:

您的参数的可能值并未完全由 if/else 分支中的选择表示。因此,最好的方法是实现一个自行决定的类,如果它负责计算您的单个结果值 stockRatingDividend。一个草图(如果没有设置最小值/最大值的一个边界,则没有吸气剂、构造函数和没有处理)将是:

public class SRDResolver {
    public class SRDRolver {
        private int peRatioMin;
        private int peRatioMax;
        private double dividendDiffMin;
        private double dividendDiffMax;
        private double payoutRatioMin;
        private double payoutRatioMax;

        private double stockRatingDividend;

        public boolean hasSolution(int peRatio,double dividendDiv,double payoutRatio){
            return peRatio > peRatioMin && peRatio <= peRatioMax  && dividendDiv > dividendDiffMin && dividendDiv <= dividendDiffMax && payoutRatio > payoutRatioMin && payoutRatio <= payoutRatioMax;
        }
    }

    
}

然后你把实例放在一个列表中。然后,您可以使用filter(i-&gt; i.hasSolution(...).findFirst() 从流式传输该列表中获取正确的实例,从而为您提供一个可选的结果。如果存在,则将其作为 stockRatingDividend,否则使用您的后备值 0。 这样,您可以在需要时轻松添加新实例,而不会弄乱 if/else。您可以在将实例放入列表时添加一些检查,以确保实例的数字空间跨度不重叠。

【讨论】:

    【解决方案3】:

    下面两个可以组合起来,因为它做同样的事情。

    else if (peRatio > 25 && peRatio <= 30 && dividendDiff >= 0.001 && payoutRatio <= 0.85) {
        int stockRatingDividend = 3;
        addItems(stockRatingDividend);
    } else if (peRatio > 30 && peRatio <= 35 && payoutRatio <= 0.95) {
        int stockRatingDividend = 3;
        addItems(stockRatingDividend);
    }
    

    另外,我建议将if-else 块重构为返回stockRatingDividend 的新方法。这将使除数计算逻辑与其他逻辑分开,这实际上会使代码更易于理解。

    if(currentDiv != 0 && fiveYearDiv != 0){
        double dividendDiff = currentDiv - fiveYearDiv;
        addItems(getStockRatingDividend(/*arguments*/));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 2014-04-02
      相关资源
      最近更新 更多