如何使用android-gpx-parser通过流优雅获取Gpx对象的所有航点?
问题:Android迁移Android-GPX-Parser获取航点时的Stream报错
背景
之前在Android项目中使用io.jenetics:jpx:2.2.0处理GPX文件,上线后发现部分GPX文件会触发不存在的依赖请求导致应用崩溃,因此迁移到com.github.ticofab:android-gpx-parser:2.2.0。
原JPX处理代码
import com.google.android.gms.maps.model.LatLng; public ArrayList<LatLng> getWaypointLatLngs(GPX gpx) { ArrayList<LatLng> latLngPoints = new ArrayList<>(); gpx.tracks() .flatMap(Track::segments) .flatMap(TrackSegment::points) .forEach(w -> latLngPoints.add( new LatLng(w.getLatitude().doubleValue(), w.getLongitude().doubleValue()))); return latLngPoints; }
迁移后的错误尝试
迁移到android-gpx-parser后,写出如下代码,但IDE报错方法引用不符合Function要求(需配合map或flatMap):
public ArrayList<LatLng> getWaypointLatLngs(Gpx gpx) { ArrayList<LatLng> latLngPoints = new ArrayList<>(); gpx.getTracks().stream().flatMap(Track::getTrackSegments) .flatMap(TrackSegment::getTrackPoints) .forEach(w -> latLngPoints.add( new LatLng(w.getLatitude().doubleValue(), w.getLongitude().doubleValue()))); return latLngPoints; }
解决方法
报错原因是:android-gpx-parser中的Track.getTrackSegments()和TrackSegment.getTrackPoints()返回的是List类型,而非JPX库中的Stream类型。flatMap需要接收一个返回Stream的函数,因此不能直接传递方法引用,需要把List转为Stream。
修正后的forEach写法
public ArrayList<LatLng> getWaypointLatLngs(Gpx gpx) { ArrayList<LatLng> latLngPoints = new ArrayList<>(); gpx.getTracks().stream() // 将List<TrackSegment>转为Stream<TrackSegment> .flatMap(track -> track.getTrackSegments().stream()) // 将List<TrackPoint>转为Stream<TrackPoint> .flatMap(segment -> segment.getTrackPoints().stream()) .forEach(point -> latLngPoints.add( new LatLng(point.getLatitude().doubleValue(), point.getLongitude().doubleValue()))); return latLngPoints; }
更优雅的Stream收集写法
可以直接用Collectors.toCollection()一步完成收集,避免手动初始化List:
import com.google.android.gms.maps.model.LatLng; import java.util.ArrayList; import java.util.stream.Collectors; public ArrayList<LatLng> getWaypointLatLngs(Gpx gpx) { return gpx.getTracks().stream() .flatMap(track -> track.getTrackSegments().stream()) .flatMap(segment -> segment.getTrackPoints().stream()) .map(point -> new LatLng(point.getLatitude().doubleValue(), point.getLongitude().doubleValue())) .collect(Collectors.toCollection(ArrayList::new)); }
内容的提问来源于stack exchange,提问作者JonR85
相关产品推荐
相关产品推荐

