在 Java 中儲存 X 和 Y 座標
1.概述
從在地圖上繪製點到捕捉使用者點擊滑鼠的精確位置,我們經常需要儲存(x, y)
座標。
Java 沒有常用的座標結構,儘管儲存座標並不罕見。在本教程中,我們將比較記錄、POJO 和陣列作為儲存這些座標的潛在方法,並探討每種方法的優缺點。
2. 使用點記錄
Java 中的記錄旨在作為簡單的資料載體。此外,它們是不可變的,並自動產生建構函式、getter、 equals()
、 hashCode()
和toString()
方法,從而顯著減少樣板程式碼。
因此,記錄非常適合表示簡單的資料聚合,例如(x, y)
座標對。
2.1. 定義記錄
這一行創建了所有必要的方法的記錄:
public record PointRecord(double x, double y) {}
我們將每個座標聲明為double
,因為它可以保存十進位值,而int
不能。
2.2. 範例記錄
讓我們驗證給定的PointRecord
實例是否正確儲存了(x, y)
座標:
@Test
void givenAPointRecord_whenUsingAccessorMethods_thenRecordReturnsCoordinatesCorrectly() {
PointRecord point = new PointRecord(30.5, 40.0);
assertEquals(30.5, point.x(), "X coordinate should be 30.5");
assertEquals(40.0, point.y(), "Y coordinate should be 40.0");
}
在此範例中,我們建立一個PointRecord
實例,其座標為(30.5, 40.0)
。然後,我們測試其存取器方法是否傳回正確的座標。
讓我們驗證具有相同座標的PointRecord
是否相等:
@Test
void givenTwoRecordsWithSameCoordinates_whenComparedForEquality_thenShouldBeEqual() {
PointRecord point1 = new PointRecord(7.0, 8.5);
PointRecord point2 = new PointRecord(7.0, 8.5);
assertEquals(point1, point2, "Records with same coordinates should be equal");
}
3.使用 Point POJO
POJO 是封裝資料的標準 Java 類別。這種方法靈活且被廣泛理解,因為它是一種經典的物件導向解決方案。
3.1 定義Point
類
我們為座標定義私有字段,並定義公共方法(getter)來存取它們:
public class PointPojo {
private final double x;
private final double y;
public PointPojo(double x, double y) {
this.x = x;
this.y = y;
}
// standard setters and getters
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PointPojo point = (PointPojo) o;
return Double.compare(point.x, x) == 0 &&
Double.compare(point.y, y) == 0;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
3.2. 例點
讓我們驗證給定的PointPojo
實例是否正確儲存(x, y)
座標:
@Test
void givenAPoint_whenUsingGetter_thenPointReturnsCoordinatesCorrectly() {
PointPojo point = new PointPojo(10.0, 20.5);
assertEquals(10.0, point.getX(), "X coordinate should be 10.0");
assertEquals(20.5, point.getY(), "Y coordinate should be 20.5");
}
在此範例中,我們建立一個PointPojo
實例,其座標為(10.0, 20.5)
。之後,我們測試其 getter 是否會傳回正確的座標。此外,我們驗證具有相同座標的PointPojo
是否相等:
@Test
void givenTwoPointsWithSameCoordinates_whenComparedForEquality_thenShouldBeEqual() {
PointPojo point1 = new PointPojo(5.1, -3.5);
PointPojo point2 = new PointPojo(5.1, -3.5);
assertEquals(point1, point2, "Points with same coordinates should be equal");
}
4. 使用java.awt
Java 的抽象視窗工具包 (AWT) 庫包含一個專門用於此目的的類別。 AWT 庫在 GUI 應用程式中特別有用。
AWT 中有一個java.awt.Point
類,但它只支援整數。 java.awt.Point2D.Double java.awt.Point2D.Double
支援雙精確度。
但是,除非我們正在建立基於 AWT 的應用程序,否則我們應該選擇其他解決方案。
5.使用數組
最簡單的方法是使用包含兩個元素的double
數組。按照慣例,第一個元素儲存x
座標,第二個元素儲存y
座標。
為了演示,讓我們使用一個陣列來表示座標(15.0, 25.0)
:
@Test
void givenArrayOfCoordinates_whenAccessingArrayIndices_thenReturnsCoordinatesAtCorrectIndices() {
double[] coordinates = new double[2];
coordinates[0] = 15.0; // x
coordinates[1] = 25.0; // y
assertEquals(15.0, coordinates[0], "Index 0 should be the X coordinate");
assertEquals(25.0, coordinates[1], "Index 1 should be the Y coordinate");
}
6. 選擇最佳方法
根據我們的用例,這四種方法可能都適用。首先,我們需要考慮如何使用儲存的(x, y)
座標。
因此,如果我們想要擴展資料結構,或正在使用 Java 15 或更早的版本,我們應該建立一個 POJO 。一個例子是擴展PointPojo
類,使其包含三個座標(x, y, z)
。缺點是需要額外的樣板程式碼。
或者,如果我們使用的是 Java 16 或更高版本,我們可以選擇記錄。這些記錄簡潔明了,非常適合該任務。
此外,如果我們的首要任務是提高速度,我們可以犧牲封裝性和可讀性來換取效能,使用一個包含兩個單元格double
數組。然而,我們需要了解如何實作一個數組,因為沒有強制要求數組必須恰好包含兩個元素,或者哪個索引對應哪個座標。
7. 結論
在本文中,我們探討了在笛卡爾座標系中儲存表示 Java 中一個點的一對(x, y)
座標的四種方法。
與往常一樣,範例的完整程式碼可 在 GitHub 上找到。