
在地理信息系统或路径规划等应用中,经常需要计算一系列城市两两之间的距离。假设我们有一个cities类,其中包含城市id、x坐标和y坐标,并提供一个distance方法来计算当前城市到指定坐标的距离。
初始的城市数据结构可能如下所示:
public class Cities {
int cityID;
float City_X_Location;
float City_Y_Location;
public void Initialization(int id, float x, float y) {
this.cityID = id;
this.City_X_Location = x;
this.City_Y_Location = y;
}
public void Distance(float x, float y) {
// 使用当前城市的坐标与传入的 (x, y) 计算距离
int dist = (int) Math.sqrt(Math.pow(this.City_X_Location - x, 2) + Math.pow(this.City_Y_Location - y, 2));
System.out.println(dist);
}
// 为了后续的equals方法,可能需要一个getter
public int getCityID() {
return cityID;
}
// 更好的实践是提供getter for X, Y coordinates
public float getCity_X_Location() {
return City_X_Location;
}
public float getCity_Y_Location() {
return City_Y_Location;
}
// 重写equals方法以实现基于cityID的比较
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Cities cities = (Cities) obj;
return cityID == cities.cityID;
}
@Override
public int hashCode() {
return java.util.Objects.hash(cityID);
}
}
public class Lab2 {
public static Cities[] City = new Cities[4]; // 假设有4个城市
public static void main(String[] args) {
for (int i = 0; i < City.length; i++)
City[i] = new Cities();
City[0].Initialization(0, 1, 1);
City[1].Initialization(1, 5, 5);
City[2].Initialization(2, 10, 3);
City[3].Initialization(3, 2, 7);
// 手动计算示例:从City[0]到其他城市的距离
// City[0].Distance(City[1].City_X_Location, City[1].City_Y_Location); // 3
// City[0].Distance(City[2].City_X_Location, City[2].City_Y_Location); // 8
// City[0].Distance(City[3].City_X_Location, City[3].City_Y_Location); // 6
// ...以此类推,对于所有城市对进行手动编码,效率低下且易错
}
}手动为每个城市对编写Distance调用是繁琐且不切实际的,尤其当城市数量增加时。我们需要一种自动化的方式来遍历所有城市并计算它们之间的距离。
初学者可能会尝试使用单个for循环,并通过在循环体内递增索引来访问不同的城市,如下所示:
// 错误的尝试
for (int i = 0; i < City.length; i++) {
City[i].Distance(5, 5); // 错误:这里的5,5是硬编码,并非来自其他城市
i++; // 错误:手动递增i会跳过一些城市,且无法正确配对
City[i].Distance(10, 3);
i++;
City[i].Distance(2, 7);
i++;
}这种尝试是错误的,原因如下:
立即学习“Java免费学习笔记(深入)”;
要实现每个城市与所有其他城市(除了它自身)的距离计算,我们需要使用嵌套循环。外层循环用于选择一个“当前城市”,内层循环用于选择一个“目标城市”与当前城市进行比较。同时,需要一个条件判断来避免城市与自身进行距离计算。
Java的增强型for循环(foreach循环)提供了一种简洁的方式来遍历集合或数组。
public class Lab2 {
// ... (City数组和Initialization部分与上面相同) ...
public static void main(String[] args) {
// ... (初始化城市数据) ...
System.out.println("--- 使用增强型for循环计算所有城市对距离 ---");
// 外层循环:选择当前城市
for (Cities currentCity : City) {
// 内层循环:选择目标城市
for (Cities otherCity : City) {
// 避免城市与自身进行比较
if (!currentCity.equals(otherCity)) { // 假设Cities类已正确重写equals方法
// 调用当前城市的Distance方法,传入目标城市的坐标
System.out.print("距离从 City[" + currentCity.getCityID() + "] 到 City[" + otherCity.getCityID() + "]: ");
currentCity.Distance(otherCity.getCity_X_Location(), otherCity.getCity_Y_Location());
}
}
}
}
}代码解释:
对于不熟悉增强型for循环的开发者,也可以使用传统的基于索引的for循环实现相同的功能:
public class Lab2 {
// ... (City数组和Initialization部分与上面相同) ...
public static void main(String[] args) {
// ... (初始化城市数据) ...
System.out.println("--- 使用传统索引型for循环计算所有城市对距离 ---");
// 外层循环:选择当前城市的索引
for (int i = 0; i < City.length; i++) {
// 内层循环:选择目标城市的索引
for (int j = 0; j < City.length; j++) {
// 避免城市与自身进行比较
if (i != j) { // 比较索引即可避免自身比较
// 获取当前城市和目标城市对象
Cities currentCity = City[i];
Cities otherCity = City[j];
// 调用Distance方法
System.out.print("距离从 City[" + currentCity.getCityID() + "] 到 City[" + otherCity.getCityID() + "]: ");
currentCity.Distance(otherCity.getCity_X_Location(), otherCity.getCity_Y_Location());
}
}
}
}
}代码解释:
equals()方法的重要性: 如果使用!currentCity.equals(otherCity)来避免自身比较,确保Cities类已正确重写equals方法和hashCode方法。通常,equals方法会基于对象的唯一标识符(如cityID)来判断两个对象是否逻辑相等。如果未重写,equals方法默认行为与==操作符相同,即比较对象引用,这在数组中每个对象都是独立实例的情况下也能工作。
数据封装: 在Cities类中,City_X_Location和City_Y_Location等属性建议设置为private,并通过公共的getter方法(如getCity_X_Location()和getCity_Y_Location())来访问,以遵循面向对象编程的封装原则。
public class Cities {
private int cityID; // 设为私有
private float City_X_Location; // 设为私有
private float City_Y_Location; // 设为私有
// ... 省略Initialization方法,通常构造函数更合适 ...
// 提供公共的getter方法
public float getCity_X_Location() {
return City_X_Location;
}
public float getCity_Y_Location() {
return City_Y_Location;
}
// ... 其他方法和重写的equals/hashCode ...
}避免重复计算: 上述方法计算的是从A到B的距离,以及从B到A的距离。如果距离是双向对称的(即Distance(A,B) == Distance(B,A)),并且你只关心唯一的城市对,可以优化内层循环,避免重复计算。例如,内层循环可以从i + 1开始:
// 优化:避免重复计算 (A到B和B到A视为同一对)
for (int i = 0; i < City.length; i++) {
for (int j = i + 1; j < City.length; j++) { // j从 i+1 开始
Cities cityA = City[i];
Cities cityB = City[j];
System.out.print("距离从 City[" + cityA.getCityID() + "] 到 City[" + cityB.getCityID() + "]: ");
cityA.Distance(cityB.getCity_X_Location(), cityB.getCity_Y_Location());
// 如果需要,也可以计算 cityB.Distance(cityA.getCity_X_Location(), cityA.getCity_Y_Location());
// 但通常情况下,距离是对称的,只需计算一次
}
}这种优化将只计算一半的距离对,减少了计算量。
通过本教程,我们学习了如何利用Java中的嵌套for循环高效地计算一个城市集合中所有不同城市对之间的距离。关键在于:
掌握这些技巧将有助于编写更健壮、更高效的Java代码来处理数据集合中的两两比较问题。
以上就是Java中利用循环计算城市间距离的教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号