使用Comparator.comparingDouble时Driver被识别为Object类型的问题
解决Comparator排序中Lambda参数类型被识别为Object的问题
问题场景
要将骑手与最近的可用司机匹配,需对List<Driver>先按距离骑手的远近排序,再按driver_id排序。但使用Collections.sort()结合Comparator.comparingDouble()链式调用时,Lambda表达式中的driver变量被识别为Object类型,必须显式强转才能调用getLocation()或getDriver_id()方法,期望无需强转实现排序。
原代码
private List<Driver> findNearbyDrivers(Rider rider) { List<Driver> availableDriverList = getAvailableDriverList(); List<Driver> nearbyDrivers = new ArrayList<>(); for (Driver driver : availableDriverList) { if (calculateDistance(rider.getLocation(), driver.getLocation()) <= MAX_DISTANCE_IN_KM) { nearbyDrivers.add(driver); } } Collections.sort(nearbyDrivers, Comparator.comparingDouble(driver -> calculateDistance(rider.getLocation(),driver.getLocation())) .thenComparing(driver -> ((Driver) driver).getDriver_id()) ); return nearbyDrivers; } public double calculateDistance(Location rider,Location driver){ double distance = Math.sqrt(Math.pow(driver.getxPosition() - rider.getxPosition(), 2) + Math.pow(driver.getyPosition() - rider.getyPosition(), 2)); return distance; }
报错信息
Comparator.comparingDouble(driver -> calculateDistance(rider.getLocation(),driver.getLocation())) ^ symbol: method getLocation() location: variable driver of type Object
问题原因
Java编译器在链式调用Comparator.comparingDouble().thenComparing()时,若未提供足够的类型提示,可能无法正确推断泛型参数,导致Lambda表达式的参数被默认识别为Object类型。
解决方案
以下两种方法可让编译器正确识别driver为Driver类型,无需强转:
方法1:显式指定comparingDouble的泛型类型
通过<Driver>明确泛型参数,直接告知编译器当前Comparator操作的是Driver对象:
Collections.sort(nearbyDrivers, Comparator.<Driver>comparingDouble(driver -> calculateDistance(rider.getLocation(), driver.getLocation())) .thenComparing(Driver::getDriver_id) );
同时thenComparing可改用方法引用Driver::getDriver_id,代码更简洁。
方法2:拆分Comparator链式调用为独立变量
将排序逻辑拆分为多个变量,让编译器通过变量类型明确泛型参数:
// 先定义按距离排序的Comparator Comparator<Driver> distanceComparator = Comparator.comparingDouble( driver -> calculateDistance(rider.getLocation(), driver.getLocation()) ); // 再追加按driver_id排序的规则 Comparator<Driver> finalComparator = distanceComparator.thenComparing(Driver::getDriver_id); // 执行排序 Collections.sort(nearbyDrivers, finalComparator);
修改后完整代码示例
private List<Driver> findNearbyDrivers(Rider rider) { List<Driver> availableDriverList = getAvailableDriverList(); List<Driver> nearbyDrivers = new ArrayList<>(); for (Driver driver : availableDriverList) { if (calculateDistance(rider.getLocation(), driver.getLocation()) <= MAX_DISTANCE_IN_KM) { nearbyDrivers.add(driver); } } // 使用显式泛型的方式实现排序 Collections.sort(nearbyDrivers, Comparator.<Driver>comparingDouble(driver -> calculateDistance(rider.getLocation(), driver.getLocation())) .thenComparing(Driver::getDriver_id) ); return nearbyDrivers; } public double calculateDistance(Location rider,Location driver){ double distance = Math.sqrt(Math.pow(driver.getxPosition() - rider.getxPosition(), 2) + Math.pow(driver.getyPosition() - rider.getyPosition(), 2)); return distance; }
内容的提问来源于stack exchange,提问作者Saurabh Patil
相关产品推荐
相关产品推荐

