0

0

Java中利用循环计算城市间距离的教程

心靈之曲

心靈之曲

发布时间:2025-10-11 10:53:01

|

364人浏览过

|

来源于php中文网

原创

Java中利用循环计算城市间距离的教程

本文旨在指导读者如何在Java中高效地使用嵌套循环,以计算一个城市集合中任意两个不同城市之间的距离。通过分析手动计算的局限性、错误的循环尝试,并提供正确的嵌套循环实现,文章将详细讲解如何遍历所有城市对、避免自身比较,并强调了代码封装和equals方法重写的最佳实践,以生成一个结构清晰、可读性强的专业教程。

1. 问题背景与手动计算的局限性

在地理信息系统或路径规划等应用中,经常需要计算一系列城市两两之间的距离。假设我们有一个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调用是繁琐且不切实际的,尤其当城市数量增加时。我们需要一种自动化的方式来遍历所有城市并计算它们之间的距离。

2. 错误的循环尝试与分析

初学者可能会尝试使用单个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免费学习笔记(深入)”;

  1. 编码坐标: Distance(5, 5)等调用中的坐标是固定的,而不是动态地获取其他城市的坐标。
  2. 不正确的索引递增: i++操作在每次循环迭代中被执行了多次,导致i的值跳跃式增长,无法遍历所有城市,也无法形成正确的城市对。
  3. 无法实现两两比较: 单个循环无法实现“每个城市与所有其他城市”的比较逻辑。

3. 正确的解决方案:嵌套循环

要实现每个城市与所有其他城市(除了它自身)的距离计算,我们需要使用嵌套循环。外层循环用于选择一个“当前城市”,内层循环用于选择一个“目标城市”与当前城市进行比较。同时,需要一个条件判断来避免城市与自身进行距离计算。

3.1 使用增强型for循环

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 (Cities currentCity : City): 外层循环遍历City数组中的每一个Cities对象,将其赋值给currentCity。这代表了我们要计算距离的起始城市。
  • for (Cities otherCity : City): 内层循环也遍历City数组,将其赋值给otherCity。这代表了我们要计算距离的目标城市。
  • if (!currentCity.equals(otherCity)): 这是关键的条件判断。它确保我们不会计算一个城市到它自身的距离。为了使equals方法正常工作,Cities类必须正确重写equals方法(通常基于唯一的城市ID)。如果equals方法未重写,默认的equals行为是比较对象的引用,即currentCity == otherCity,这对于数组中不同的对象引用也是有效的。
  • currentCity.Distance(otherCity.getCity_X_Location(), otherCity.getCity_Y_Location()): 调用currentCity对象的Distance方法,传入otherCity的X和Y坐标,从而计算出它们之间的距离。

3.2 使用传统索引型for循环

对于不熟悉增强型for循环的开发者,也可以使用传统的基于索引的for循环实现相同的功能:

LALALAND
LALALAND

AI驱动的时尚服装设计平台

下载
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());
                }
            }
        }
    }
}

代码解释:

  • for (int i = 0; i 分别使用索引i和j来遍历城市数组。
  • if (i != j): 通过比较索引来判断是否是同一个城市。这种方式简单直接,不需要Cities类重写equals方法。

4. 注意事项与最佳实践

  1. equals()方法的重要性: 如果使用!currentCity.equals(otherCity)来避免自身比较,确保Cities类已正确重写equals方法和hashCode方法。通常,equals方法会基于对象的唯一标识符(如cityID)来判断两个对象是否逻辑相等。如果未重写,equals方法默认行为与==操作符相同,即比较对象引用,这在数组中每个对象都是独立实例的情况下也能工作。

  2. 数据封装: 在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 ...
    }
  3. 避免重复计算: 上述方法计算的是从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());
            // 但通常情况下,距离是对称的,只需计算一次
        }
    }

    这种优化将只计算一半的距离对,减少了计算量。

5. 总结

通过本教程,我们学习了如何利用Java中的嵌套for循环高效地计算一个城市集合中所有不同城市对之间的距离。关键在于:

  1. 使用外层循环选择当前城市。
  2. 使用内层循环选择目标城市。
  3. 通过条件判断(if (!currentCity.equals(otherCity)) 或 if (i != j))避免城市与自身进行比较。
  4. 遵循封装原则,使用getter方法访问对象属性。
  5. 根据需求考虑优化,避免重复计算对称距离。

掌握这些技巧将有助于编写更健壮、更高效的Java代码来处理数据集合中的两两比较问题。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

831

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

735

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

733

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

396

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

25

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.4万人学习

C# 教程
C# 教程

共94课时 | 6.4万人学习

Java 教程
Java 教程

共578课时 | 44.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号