如何避免java中重复的代码?

时间:2016-02-09 01:24:09

标签: java

我只是编程的初学者。 uf是一个union-find类,其方法union连接两个节点的根。 如果打开任何邻居,这段代码负责打开网格的站点并将站点与其邻居联合。如果其中一个邻居已满,则填写与该站点连接的所有节点。 这是实际的代码:

        if(i == 1){
            uf.union(len*len, xyTo1D(i,j));
            if(existAndOpen(i+1,j)){
                uf2.union(xyTo1D(i+1,j), xyTo1D(i,j));
                uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
            }
            if(existAndOpen(i-1,j)){
                uf2.union(xyTo1D(i-1,j), xyTo1D(i,j));
                uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
            }
            if(existAndOpen(i,j-1)){
                uf2.union(xyTo1D(i,j-1), xyTo1D(i,j));
                uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
            }
            if(!(j == len && i == len)){
                if(existAndOpen(i,j+1)){
                    uf2.union(xyTo1D(i,j+1), xyTo1D(i,j));
                    uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
                }
            }
        }
        else{
        if(existAndFull(i+1,j)){
            uf2.union(xyTo1D(i+1,j), xyTo1D(i,j));
            uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
        }
        if(existAndFull(i-1,j)){
            uf2.union(xyTo1D(i-1,j), xyTo1D(i,j));
            uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
        }
        if(existAndFull(i,j-1)){
            uf2.union(xyTo1D(i,j-1), xyTo1D(i,j));
            uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
        }
        if(!(j== len && i == len)){
            if(existAndFull(i,j+1)){
                uf2.union(xyTo1D(i,j+1), xyTo1D(i,j));
                uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
            }
        }
        if(existAndOpen(i+1,j)){
            uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
        }
        if(existAndOpen(i-1,j)){
            uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
        }
        if(existAndOpen(i,j-1)){
            uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
        }
        if(!(j== len && i == len)){
            if(existAndOpen(i,j+1)){
                uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
            }
        }
    }
    }

如何简化代码?

4 个答案:

答案 0 :(得分:6)

试试这个

boolean f1(int a, int b) { }
boolean f2(int a, int b) { }
void A(int a, int b) { }

void testAndA(BiPredicate<Integer, Integer> p, int a, int b) {
    if (p.test(a, b))
        A(a, b);
}

    if(x == 1){
        testAndA(this::f1, x + 1, y);
        testAndA(this::f1, x, y + 1);
    } else {
        testAndA(this::f2, x + 1, y);
        testAndA(this::f2, x, y + 1);
    }

答案 1 :(得分:1)

你可以编写一个循环来遍历可以传递给f1()的所有不同值,例如:

for (int deltax = -1; deltax <= 1; deltax++) {
    for (int deltay = -1; deltay <= 1; deltay++) {
        if (f1(x + deltax, y + deltay)) {
            A(x + deltax, y + deltay);
        }
    }
}

当然,根据您需要检查的条件,更改deltax和deltay的起始值和结束值。

答案 2 :(得分:1)

你说每个街区都有“更多if语句”。在行间阅读,我认为这意味着您需要拨打f1 / f2A,但使用不同的xy抵消。

这是一个程序,它显示了重构代码以避免编码重复的方法。其主要特点是:

  • 它使用面向对象来抽象内部if块。
  • 它使用offsets数组来表示每个内部x块的y / if偏移量。
  • doIt()方法使用循环来调用内部if块。

    public class Main {
    
        static interface F {
          void f(int i, int j);
        }
    
        static class F1Caller implements F {
          public void f(int a, int b) {
            if (f1(a, b)) {
              A(a, b);
            }
          }
        }
    
        static class F2Caller implements F {
          public void f(int a, int b) {
            if (f2(a, b)) {
              A(a, b);
            }
          }
        }
    
        static boolean f1(int a, int b) { System.out.print("  f1. "); return true; }
        static boolean f2(int a, int b) { System.out.print("  f2. "); return true; }
        static void A(int a, int b) { System.out.println("a: " + a + ", b: " + b); }
    
        static F1Caller f1Caller = new F1Caller();
        static F2Caller f2Caller = new F2Caller();
    
        // x and y offsets for each call to f1/f2.
        // Add more offset rows, as needed.
        static int offsets[][] = {
            {1,  0},
            {0, -1}
        };
    
        static void doIt(int x, int y) {
          System.out.println("x: " + x + ", y: " + y);
    
          F f = (x == 1) ? f1Caller : f2Caller;
          for (int k = 0; k < offsets.length; k++) {
              f.f(x + offsets[k][0], y + offsets[k][1]);
          }
        }
    
    
        public static void main(String[] args) {
            doIt(0, 0);
            doIt(1, 0);
        }
    }
    

上述程序的输出是:

x: 0, y: 0
  f2. a: 1, b: 0
  f2. a: 0, b: -1
x: 1, y: 0
  f1. a: 2, b: 0
  f1. a: 1, b: -1

答案 3 :(得分:1)

您可以将功能组合在一起。

使用开关。

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

将其与for循环集成:

public static boolean func(int a, int b, int fun)
{
     boolean output = false;
     switch(fun)
     {
     case 1:
         //do stuff
         output = true;
         break;
     case 2:
         //do stuff
         output = true;
         break;
     default:
         //unknown function handling
        output = false;
     }
     return output;
}