如何重构此 java 代码

How to refactor this java code

我有下面的 java 方法叫做 solution,有两个大的 for 循环,如你所见,这两个 for 循环非常相似,所以我认为可以重构通过使用像 public int getElementSize(ArrayList<Integer> factor1, ArrayList<Integer> factor2) 这样的方法来编写代码,它完成 for 循环的工作,所以我可以用不同的参数调用该方法两次,而不是重复两次 for 循环。但是因为这两个for循环有不同的循环顺序,一个是从头到尾,一个是从尾到头,除此之外,循环的所有其他部分都是相同的,有什么想法如何重构这段代码?

class Solution {
    public int solution(int[] A) {
        ArrayList<Integer> factor1 = new ArrayList<Integer>();
        ArrayList<Integer> factor2 = new ArrayList<Integer>();

        int factor = 1;
        int N = A.length;
        while(factor * factor <= N){
            if(N % factor == 0){
                factor1.add(factor);
                factor2.add(N / factor);
            }
            factor++;
        }

        for(int i = 1; i < factor2.size(); i++){
            int blockSize = factor2.get(i);
            int elementSize = factor1.get(i);
            int peaks = 0;
            for(int j = 0; j < blockSize; j++){
                boolean hasPeak = false;
                for(int k = elementSize * j; k < elementSize * (j + 1); k++){
                    if(k > 0 && k < N - 1){
                        if(A[k] > A[k - 1] && A[k] > A[k + 1])
                            hasPeak = true;
                    }    
                } 
                if(!hasPeak)
                   break; 
                else
                   peaks++;
            }
            if(peaks == blockSize)
                return blockSize;
        }

        for(int i = factor1.size() - 1; i >= 0; i--){
            int blockSize = factor1.get(i);
            int elementSize = factor2.get(i);
            int peaks = 0;
            for(int j = 0; j < blockSize; j++){
                boolean hasPeak = false;
                for(int k = elementSize * j; k < elementSize * (j + 1); k++){
                    if(k > 0 && k < N - 1){
                        if(A[k] > A[k - 1] && A[k] > A[k + 1])
                            hasPeak = true;
                    }    
                } 
                if(!hasPeak)
                   break; 
                else
                   peaks++;
            }
            if(peaks == blockSize)
                return blockSize;    
        }

        return 0;
    }
}

可以将for循环里面的代码重构到new方法里面,将两个大的for循环移到new方法中,这样两个循环的顺序还是独立的,基本上如下图,正确性有待验证,这只是一种思路不再赘述:

    class Solution {
    public int solution(int[] A) {
        ArrayList<Integer> factor1 = new ArrayList<Integer>();
        ArrayList<Integer> factor2 = new ArrayList<Integer>();       
        int factor = 1;
        int N = A.length;
        while(factor * factor <= N){
            if(N % factor == 0){
                factor1.add(factor);
                factor2.add(N / factor);
            }
            factor++;
        }

        for(int i = 1; i < factor2.size(); i++){
            int blockSize = factor2.get(i);
            int elementSize = factor1.get(i);
            int peaks = getElementSize(A, blockSize, elementSize); //call the method
            if(peaks == blockSize)
                return blockSize;
        }

        for(int i = factor1.size() - 1; i >= 0; i--){
            int blockSize = factor1.get(i);
            int elementSize = factor2.get(i);
            int peaks = getElementSize(A, blockSize, elementSize); //call the method
            if(peaks == blockSize)
                return blockSize;    
        }

        return 0;
    }

    //this method include the code which was repeated inside the loops 
    public int getElementSize(int[] A, int blockSize, int elementSize){
        int peaks = 0;
        int N = A.length;
        for(int j = 0; j < blockSize; j++){
            boolean hasPeak = false;
            for(int k = elementSize * j; k < elementSize * (j + 1); k++){
                if(k > 0 && k < N - 1){
                    if(A[k] > A[k - 1] && A[k] > A[k + 1])
                        hasPeak = true;
                }    
            } 
            if(!hasPeak)
                break; 
            else
                peaks++;
        }

        return peaks;
    }
}

这个怎么样?

条件运算符,?和:类似于,(这些被称为三元运算符并在编译时解析为 if else 块)

if(condition) {
this();
} else { 
that();
}

在上面,您可以单行表示,(condition ? this() : that())

class Solution {
public int solution(int[] A) {
    ArrayList<Integer> factor1 = new ArrayList<Integer>();
    ArrayList<Integer> factor2 = new ArrayList<Integer>();

    int factor = 1;
    int N = A.length;
    while(factor * factor <= N){
        if(N % factor == 0){
            factor1.add(factor);
            factor2.add(N / factor);
        }
        factor++;
    }
    // let i = 0 to be factor2, i = 1 is factor 1
    for(int i = 0; i < 2; i++) { 
    for(int x = (i == 0 ? 1 : factor1.size() - 1); (i == 0 ? x < factor2.size() : x >= 0); (i == 0 ? x++ : x--)){
        int blockSize = (i == 0 ? factor2.get(x) : factor1.get(x));
        int elementSize = (i == 0 ? factor1.get(x) : factor2.get(x));
        int peaks = 0;
        for(int j = 0; j < blockSize; j++){
            boolean hasPeak = false;
            for(int k = elementSize * j; k < elementSize * (j + 1); k++){
                if(k > 0 && k < N - 1){
                    if(A[k] > A[k - 1] && A[k] > A[k + 1])
                        hasPeak = true;
                }    
            } 
            if(!hasPeak)
               break; 
            else
               peaks++;
        }
        if(peaks == blockSize)
            return blockSize;
            }
        }

    return 0;
    }
}