首页 > Java > java教程 > 正文

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

心靈之曲
发布: 2025-10-11 10:53:01
原创
351人浏览过

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循环实现相同的功能:

美间AI
美间AI

美间AI:让设计更简单

美间AI 45
查看详情 美间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 < City.length; i++) 和 for (int j = 0; j < City.length; j++): 分别使用索引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中利用循环计算城市间距离的教程的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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