0

スプレッドシートで作業している課題があり、インストラクターから渡されました。

Rangeというクラスを実装するように求められています。このクラスは、2つの位置(それぞれが列と行を表す2つのintで構成され、たとえばnew Position(1,2))を受け入れ、最下位の行と列を見つけて新しい位置を作成します。これらの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;
    }   
}

ただし、問題は、実際には機能せず、返されるリストが空であるということです。それでは、なぜですか。誰かがエラーを見つけることができますか?

4

1 に答える 1

1

それがうまくいかない理由はわかりません。わかりました、ここにいくつかの問題があります:

  • positionList = new ArrayList<>();コンパイルされません。それは違いないpositionList = new ArrayList<Position>();
  • Jodakaが言ったように、2回目に取得するとリスト内のすべてのポジションを2回取得します(4回目と呼ぶと3回というようになります)。
  • 実装には最初の列と行が含まれますが、最後の列は含まれません(ループ内で試しi <= maxColumnてください)。j <= maxRow

私のテストでは、Positionの代わりにPointsを使用し、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()をもう一度呼び出すと、すべてのポイントが2回表示されます。リストは1回作成しますが、getPoints()を呼び出すたびにポイントを追加します。

いくつかの可能性があります:

  1. ArrayListは、コンストラクターではなくgetPoints()メソッドで作成できます。しかし、通常、このメソッドを呼び出すたびにまったく新しいリストを作成することは望ましくありません...
  2. リストをフィールドに格納し、コンストラクターで計算して、フィールドを返すゲッターのみを使用することができます。
  3. 2番目の可能性と同様ですが、リストをオンデマンドで計算できます。したがって、コンストラクターでは計算せず、ゲッターで計算します。それ以外の場合は、保存されたリストを使用します。

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;
        }
    }
    
于 2013-01-23T08:22:19.167 に答える