簡體   English   中英

如何更換if的長鏈

[英]How to replace a long chain of if

我有一個包含3個整數i,j和k的對象。

那些整數可以有一個減號(M),一個加號(P)或者為空(O)。

因此,任何此類對象都可以歸類為以下類別之一:MMM,MMP,MPM,MPP,PMM,PMP,PPM,PPP,OMM,OMP,OPM,OPP,MOM,MOP,POM,POP,MMO,MPO,PMO ,PPO,MOO,POO,OMO,OPO,OOM,OOP,OOO。

我想對這種類型的對象執行計算,這些對象將根據對象的類別而有所不同。

我的對象不僅包含這三個整數,還包含將在計算中使用的其他信息。

我的兩個問題是:

  • 如何從i,j和k值中推導出對象的類別?

  • 如何實現正確算法的選擇?

我做了一個天真的實現,使用枚舉和很多if ... else,但我對結果不滿意,尤其是if ... else部分。

任何更好,更面向對象的想法?

數據類:

public class Data {
    private int i, j, k;
    private double otherData;
    private Category category;

    public void init(int i, int j, int k) {
        this.i = i;
        this.j = j;
        this.k = k;

        if (i < 0) {
            if (j < 0) {
                if (k < 0) {
                    category = Category.MMM;
                } else if (k > 0) {
                    category = Category.MMP;
                } else//(k >= 0)
                {
                    category = Category.MMO;
                }
            } else//(j >= 0)
            {
                if (k < 0) {
                    category = Category.MPM;
                    if (j == 0)
                        category = Category.MOM;
                } else//(k >= 0)
                {
                    if ((j == 0) && (k == 0))
                        category = Category.MOO;
                    else if (k == 0)
                        category = Category.MPO;
                    else if (j == 0)
                        category = Category.MOP;
                    else
                        category = Category.MPP;
                }
            }
        } else//(i >= 0)
        {
            if (j < 0) {
                if (k < 0) {
                    category = Category.PMM;
                    if (i == 0)
                        category = Category.OMM;
                } else//(k >= 0)
                {
                    if ((i == 0) && (k == 0))
                        category = Category.OMO;
                    else if (k == 0)
                        category = Category.PMO;
                    else if (i == 0)
                        category = Category.OMP;
                    else
                        category = Category.PMP;
                }
            } else//(j >= 0)
            {
                if (k < 0) {
                    if ((i == 0) && (j == 0))
                        category = Category.OOM;
                    else if (i == 0)
                        category = Category.OPM;
                    else if (j == 0)
                        category = Category.POM;
                    else
                        category = Category.PPM;
                } else//(k > 0)
                {
                    if (i == 0) {
                        if (j == 0)
                            category = Category.OOP;
                        else if (k == 0)
                            category = Category.OPO;
                        else
                            category = Category.OPP;
                    } else {
                        if ((j == 0) && (k == 0))
                            category = Category.POO;
                        else if (j == 0)
                            category = Category.POP;
                        else if (k == 0)
                            category = Category.PPO;
                        else
                            category = Category.PPP;
                    }
                }
            }
        }
    }

    public void computeSomething() {
        category.computeSomething(this);
    }

    public double getOtherData() {
        return otherData;
    }

    public void setOtherData(double otherData) {
        this.otherData = otherData;
    }
}

枚舉類:

public enum Category {
    MMM {
        @Override
        public void computeSomething(Data data) {
            // Do something
        }
    },
    MMP {
        @Override
        public void computeSomething(Data data) {
            // Do something else
        }
    }
    // Omitted code for clarity

    public abstract void computeSomething(Data data);
}

有關完整用例上下文,請參閱http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.147.2010&rep=rep1&type=pdf

此代碼等同於您的init方法:

public void init(int i, int j, int k) {
    this.i = i;
    this.j = j;
    this.k = k;
    category=Category.valueOf( (i<0?"M":(i==0?"O":"P"))
                              +(j<0?"M":(j==0?"O":"P"))
                              +(k<0?"M":(k==0?"O":"P")));
}

正如@Robert所建議的那樣,你也可以這樣做:

private void init(int i, int j, int k){
    this.i = i;
    this.j = j;
    this.k = k;
    category = Category.fromInts(i,j,k);
}

enum Category {
        MMM, MMP, MPM, MPP, PMM, PMP, PPM, PPP, 
        OMM, OMP, OPM, OPP, MOM, MOP, POM, POP, 
        MMO, MPO, PMO, PPO, MOO, POO, OMO, OPO, 
        OOM, OOP, OOO;

        static Category fromInts(int i, int j, int k){
            return Category.valueOf( (i<0?"M":(i==0?"O":"P"))
                                    +(j<0?"M":(j==0?"O":"P"))
                                    +(k<0?"M":(k==0?"O":"P")));
        };
}

關於計算算法的選擇,從枚舉中刪除它可能是一個好主意,並采取類似這樣的方法:

public class Data {
    ...
    public void computeSomething() {
        swith(category){
            case MMM : computeMMM();break;
            case MMO : computeMMO();break;
            ...
        }
    }

    private void computeMMM(){
        ...
    }

    private void computeMMO(){
        ...
    }
}

Q1:這是一種避免創建然后散列字符串的替代方法。

private static Category[] CATEGORIES = {
        MMM, MMO, MMP, MOM, MOO, MOP, MPM, MPO, MPP,
        OMM, OMO, OMP, OOM, OOO, OOP, OPM, OPO, OPP,
        PMM, PMO, PMP, POM, POO, POP, PPM, PPO, PPP
};

private int toTernary(int x) {
    // (This method will probably be in-lined ...)
    if (x < 0) return 0;
    else if (x == 0) return 1;
    else return 2;
}

private Category init(int i, int, j, int k) {
    int index = 9 * toTernary(i) + 3 * toTernary(j) + toTernary(k);
    return CATEGORIES[i];
}

Q2:您可以構建一個“算法”對象數組,按Category序號的索引編制索引。

我可以指出你在switch語句的方向嗎? https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

我已經多次使用它來擺脫麻煩如果鏈

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM