0

我一直在尝试我正在尝试制作的游戏。我发现我有两种相同的方法,除了 for 循环,它只是前者的相反。

我试图做到这一点,这样我就可以向前或向后使用相同的代码。我最终得到:

for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))

A) B) 我想和大家分享这个概念。

B)我很好奇这种循环的效率。我知道它在访问时计算目标数和增量因子,但我不知道如何测试它。

C)当我在它的时候,我发现了一行可以交换两个变量而不使用临时变量。阅读需要一点时间,但这是否比使用 temp 更好(代码方面)?(下面主要的第三行)

我已经对其功能进行了测试,它按预期运行。如果第二个数字大于第一个数字,则向上计数。如果没有,它会倒计时。我的测试代码是:

// A generic loop that can go up or down
import java.io.*;

public class reversable
{
  public static int start = 1;
  public static int finish = 10;

   public static void main(String[] args)
  {
     for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))
     {
        System.out.println("i = " + i);
     }
     finish = (start + finish) - (start = finish);  
System.out.println("Finish = " + finish);
System.out.println("Start = " + start);
     for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))
     {
        System.out.println("i = " + i);
     }
     finish = 10;
     for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))
     {
        System.out.println("i = " + i);
     }
  }
}

根据评论,这是否可以接受:

public static void reversable (int i, int j)
{
  if (i > j) int inc = -1;  // Count down
  else       int inc = 1;  // Count up
  j += inc;
  for (i; i != j; i += inc)
  {
    dostuff();
    morestuff();
    mostuff();
  }
}
4

4 回答 4

15

您应该努力编写可读的代码,而不是在一行中完成很多事情或具有花哨技巧的代码。

如果我和你一起做一个项目,我可能想在我第一次读到那个 for 循环之后扼杀你,也就是说,如果我的头没有爆炸,试图首先理解它。分配中的分配也是如此。

于 2010-11-03T02:28:51.143 回答
10

如果我在生产中看到此代码,我会立即将其重构为更易读的内容,这可能与您开始时的内容相似。

想想你想要减少代码重复的原因。这是为了使您的代码更易于维护。你觉得你已经做到了吗?

当我在做的时候,我发现了一行可以在不使用临时变量的情况下交换两个变量。阅读需要一点时间,但这是否比使用 temp 更好(代码方面)?

这仅适用于数字类型,所以我觉得它没有那么有用。您使不知道该技巧的人对代码的可读性降低,从而减慢了代码的维护速度。我认为节省一个临时变量不值得。

于 2010-11-03T02:36:21.007 回答
6

嗯,不是想成为砖头,但我认为你试图写:

public static void doAction(int i) {
    System.out.println("i = " + i);
}

public static void loopValues(int i, int j) {
    if (i > j) while (i >= j) doAction(i--);
    else       while (i <= j) doAction(i++);;
}

public static void main(String[] args) {
    int start = 1, finish = 10;
    loopValues(start, finish);
    loopValues(finish, start);
}

你有 2 个循环的原因是效率和你的案例可读性。比较是一项代价高昂的操作,您通常不希望为循环添加额外的比较来改变其正常进程。

于 2010-11-03T02:55:18.920 回答
0

事实上,代码很难遵循......但批评者已经足够了。当有人要求只有循环不同的可重用方法时,唯一想到的是Iterator. 迭代器模式正是这种可重用案例所需要的。如果您将迭代器包装在Iterable接口中,那么您可以轻松地在for块中使用它。例子 :

public class IntegerRange implements Iterable<Integer> {
   private boolean reverse;
   private int start;
   private int end;

   public IntegerRange(int start, int end) {
      this.reverse = (start > end);
      this.start = start;
      this.end = end;
   }

   @Override
   public Iterator<Integer> iterator() {
      return new IntegerIterator();
   }


   private class IntegerIterator implements Iterator<Integer> {

      private int current;

      private IntegerIterator() {
         current = start;
      }

      @Override
      public boolean hasNext() {
         if (reverse) {
            return (end <= current);
         } else {
            return (current <= end);
         }
      }

      @Override
      public Integer next() {
         if (!hasNext()) {
            throw new NoSuchElementException();
         }
         if (reverse) {
            return current--;
         } else {
            return current++;
         }
      }

      @Override
      public void remove() {
         throw new UnsupportedOperationException("Cannot remove from this iterator");
      }
   }

}

然后使用和重用你的迭代器......

static public void main(String...args) {
   doStuff(new IntegerRange(1, 10));
   doStuff(new IntegerRange(10, 1));
}

static private void doStuff(IntegerRange range) {
   for (int i : range) {
      System.out.println("i = " + i);
   }
} 

现在代码更具可读性。

于 2010-11-03T14:56:18.417 回答