这个Range类的实现有什么问题

时间:2013-01-22 15:47:44

标签: java arraylist nested-loops

我有一份工作,我正在制作电子表格,我已由我的导师递交。

我被要求实现一个名为Range的类,它接受两个位置(每个位置由两个整数组成,表示列和行,例如新位置(1,2)),然后找到最低的行和列以及构造这两个值的新位置,此位置是我的范围的左上角,并且与行和列的最高值相同。

然后我被要求上一个课程,取一系列职位的总和。所以我决定对于我的范围,它应该能够有一个方法,其中放入ArrayList的所有位置,即getPositions()方法。

在这里您可以看到该类的源代码:

package spreadsheet;

import java.lang.Math;
import java.util.ArrayList;

public class Range {

    private Position a;
    private Position b;
    private ArrayList<Position> positionList;

    // Creates a new range, where it makes sure that the positions,
    // appear in the right order, where the first position is the position
    // of the upper left corner, and the second position is the lower right corner.
    public Range(final Position a, final Position b) {
        int minColumn = Math.min(a.getColumn(),b.getColumn());
        int minRow = Math.min(a.getRow(),b.getRow());

        int maxColumn = Math.max(a.getColumn(),b.getColumn());
        int maxRow = Math.max(a.getRow(),b.getRow());

        this.a = new Position(minColumn, minRow);
        this.b = new Position(maxColumn, maxRow);
        positionList = new ArrayList<>();       
    }


    public ArrayList<Position> getPositions() {
        int minColumn = this.a.getColumn();
        int minRow = this.a.getRow();
        int maxColumn = this.b.getColumn();
        int maxRow = this.b.getRow();
        for(int i = minColumn; i < maxColumn; i++) {
            for(int j = minRow; j < maxRow; j++) {
                positionList.add(new Position(i, j));
            }
        }
        return positionList;
    }   
}

然而问题是它没有真正起作用,它返回的列表是空的,那为什么呢?有人能发现错误吗?

1 个答案:

答案 0 :(得分:1)

我认为没有理由不这样做。 好的,这里有一些问题:

  • positionList = new ArrayList<>();无法编译。必须是positionList = new ArrayList<Position>();
  • 正如Jodaka所说,当你第二次得到它时,你会在列表中两次得到每个位置(当你把它称为第四次时,你会得到三次,依此类推)。
  • 您的实现将包括第一列和第一行但不包括最后一行(在循环中尝试i <= maxColumnj <= maxRow)。

对于我的测试,我使用了Points而不是Position,并为Points使用int添加了一些强制转换作为构造函数参数但返回double。但我没有改变逻辑本身:

package spreadsheet;

import java.awt.Point;
import java.util.ArrayList;

public class Range {

private final Point a;
private final Point b;
private final ArrayList<Point> PointList;

// Creates a new range, where it makes sure that the Points,
// appear in the right order, where the first Point is the Point
// of the upper left corner, and the second Point is the lower right corner.
public Range(final Point a, final Point b) {
    int minColumn = (int) Math.min(a.getX(),b.getX());
    int minRow = (int) Math.min(a.getY(),b.getY());

    int maxColumn =(int)  Math.max(a.getX(),b.getX());
    int maxRow = (int) Math.max(a.getY(),b.getY());
    this.a = new Point(minColumn, minRow);
    this.b = new Point(maxColumn, maxRow);
    PointList = new ArrayList<Point>();
}

public ArrayList<Point> getPoints() {
    int minColumn = (int) a.getX();
    int minRow = (int) a.getY();
    int maxColumn = (int) b.getX();
    int maxRow = (int) b.getY();
    for (int i = minColumn; i < maxColumn; i++) {
        for (int j = minRow; j < maxRow; j++) {
            PointList.add(new Point(i, j));
        }
    }
    return PointList;
}

测试:

package spreadsheet;

import java.awt.Point;
import java.util.ArrayList;

import org.junit.Test;

    public class RangeTest {

    @Test
    public void testSomePoints() throws Exception {
        Range range = new Range(new Point(1, 1), new Point(5, 5));
        ArrayList<Point> points = range.getPoints();
        for (Point point : points) {
            System.out.println(point);
        }
    }
}

结果:

java.awt.Point[x=1,y=1]
java.awt.Point[x=1,y=2]
java.awt.Point[x=1,y=3]
java.awt.Point[x=1,y=4]
java.awt.Point[x=2,y=1]
java.awt.Point[x=2,y=2]
java.awt.Point[x=2,y=3]
java.awt.Point[x=2,y=4]
java.awt.Point[x=3,y=1]
java.awt.Point[x=3,y=2]
java.awt.Point[x=3,y=3]
java.awt.Point[x=3,y=4]
java.awt.Point[x=4,y=1]
java.awt.Point[x=4,y=2]
java.awt.Point[x=4,y=3]
java.awt.Point[x=4,y=4]

编辑:

如果我第二次调用getPoints(),我会两次看到每个点。 您可以创建一次列表,但每次调用getPoints()时都会添加点。

有几种可能性:

  1. 您可以在getPoints()方法中创建ArrayList,而不是在构造函数中创建。但通常你不想在每次调用这个方法时创建一个全新的列表......
  2. 您可以将列表存储在字段中,在构造函数中计算它并仅使用返回该字段的getter。
  3. 与第二种可能性相似,但您可以按需计算列表。因此,不要在构造函数中计算它,而是在getter 中计算它,如果它现在为null ,否则使用存储列表。
  4. 2。修改

    1. 选项:

      public class Range {
      
          private final Point a;
          private final Point b;
          private final ArrayList<Point> PointList;
      
          public Range(final Point a, final Point b) {
              int minColumn = (int) Math.min(a.getX(),b.getX());
              int minRow = (int) Math.min(a.getY(),b.getY());
      
              int maxColumn =(int)  Math.max(a.getX(),b.getX());
              int maxRow = (int) Math.max(a.getY(),b.getY());
              this.a = new Point(minColumn, minRow);
              this.b = new Point(maxColumn, maxRow);
          }
      
          public ArrayList<Point> getPoints() {
              PointList = new ArrayList<Point>();
              int minColumn = (int) a.getX();
              int minRow = (int) a.getY();
              int maxColumn = (int) b.getX();
              int maxRow = (int) b.getY();
              for (int i = minColumn; i < maxColumn; i++) {
                  for (int j = minRow; j < maxRow; j++) {
                      PointList.add(new Point(i, j));
                  }
              }
              return PointList;
          }
      }
      
    2. 选项:

      public class Range {
      
          private final Point a;
          private final Point b;
          private final ArrayList<Point> PointList;
      
          public Range(final Point a, final Point b) {
              int minColumn = (int) Math.min(a.getX(),b.getX());
              int minRow = (int) Math.min(a.getY(),b.getY());
      
              int maxColumn =(int)  Math.max(a.getX(),b.getX());
              int maxRow = (int) Math.max(a.getY(),b.getY());
              this.a = new Point(minColumn, minRow);
              this.b = new Point(maxColumn, maxRow);
              PointList = calcPoints();
          }
      
          private ArrayList<Point> calcPoints() {
              ArrayList<Point> list = new ArrayList<Point>();
              int minColumn = (int) a.getX();
              int minRow = (int) a.getY();
              int maxColumn = (int) b.getX();
              int maxRow = (int) b.getY();
              for (int i = minColumn; i < maxColumn; i++) {
                  for (int j = minRow; j < maxRow; j++) {
                      PointList.add(new Point(i, j));
                  }
              }
              return list;
          }
      
          public ArrayList<Point> getPoints() {
              return PointList;
          }
      }
      
    3. 选项:

      public class Range {
      
          private final Point a;
          private final Point b;
          private final ArrayList<Point> PointList;
      
          public Range(final Point a, final Point b) {
              int minColumn = (int) Math.min(a.getX(),b.getX());
              int minRow = (int) Math.min(a.getY(),b.getY());
      
              int maxColumn =(int)  Math.max(a.getX(),b.getX());
              int maxRow = (int) Math.max(a.getY(),b.getY());
              this.a = new Point(minColumn, minRow);
              this.b = new Point(maxColumn, maxRow);
          }
      
          private ArrayList<Point> calcPoints() {
              ArrayList<Point> list = new ArrayList<Point>();
              int minColumn = (int) a.getX();
              int minRow = (int) a.getY();
              int maxColumn = (int) b.getX();
              int maxRow = (int) b.getY();
              for (int i = minColumn; i < maxColumn; i++) {
                  for (int j = minRow; j < maxRow; j++) {
                      list.add(new Point(i, j));
                  }
              }
              return list;
          }
      
          public ArrayList<Point> getPoints() {
              if(PointList == null) {
                  PointList = calcPoints();
              }
              return PointList;
          }
      }