我试图将一个“老方法”循环转换为基于流的方法。循环需要一大组元素并返回落在给定半径内的子集。结果按距离排序,结果本身具有计算的距离(用于演示)。它的工作方式很好,我不需要需要 Java8-ify它。但我真的很想。 :-)如果只是为了能够在这个吸盘上去.parallel()。Java 8流:您可以捕获/重用在过滤器中计算的值吗?
美中不足的是我的...过滤器()使用的计算值(距离),然后我需要在随后的地图()步骤(构建“与距离”实例)。假定距离计算很昂贵。这里的Java 7的方式...向下滚动看到getNearestStations()方法:
public interface Coordinate {
double distanceTo(Coordinate other);
}
public class Station {
private final String name;
private final Coordinate coordinate;
public Station(String name, Coordinate coordinate) {
this.name = name;
this.coordinate = coordinate;
}
public String getName() {
return name;
}
public Coordinate getCoordinate() {
return coordinate;
}
}
public class StationWithDistance extends Station implements Comparable<StationWithDistance> {
private final double distance;
public StationWithDistance(Station station, double distance) {
super(station.getName(), station.getCoordinate());
this.distance = distance;
}
public double getDistance() {
return distance;
}
public int compareTo(StationWithDistance s2) {
return Double.compare(this.distance, s2.distance);
}
}
// Assume this contains many entries
private final List<Station> allStations = new ArrayList<>();
public List<StationWithDistance> getNearbyStations(Coordinate origin, double radius) {
List<StationWithDistance> nearbyStations = new ArrayList<>();
for (Station station : allStations) {
double distance = origin.distanceTo(station.getCoordinate());
if (distance <= radius) {
nearbyStations.add(new StationWithDistance(station, distance));
}
}
Collections.sort(nearbyStations);
return nearbyStations;
}
现在...这里是一个基于流的哑/蛮力的方法。需要注意的是它执行的距离计算两次(stoopid),但它是一个一步接近平行()美化版:
public List<StationWithDistance> getNearbyStationsNewWay(Coordinate origin, double radius) {
return allStations.stream()
.parallel()
.filter(s -> origin.distanceTo(s.getCoordinate()) <= radius)
.map(s -> new StationWithDistance(s, origin.distanceTo(s.getCoordinate())))
.sorted()
.collect(Collectors.toList());
}
试图找出一个更好的办法(TM),这是我想出来的到目前为止,为了避免重复计算:
public List<StationWithDistance> getNearbyStationsNewWay(Coordinate origin, double radius) {
return allStations.stream()
.parallel()
.map(s -> new StationWithDistance(s, origin.distanceTo(s.getCoordinate())))
.filter(s -> s.getDistance() <= radius)
.sorted()
.collect(Collectors.toList());
}
...但产生的垃圾 - 最创建的StationWithDistance实例得到过滤掉。
我错过了什么?有没有一种在Java 8中做到这一点的优雅方式:(a)避免重复计算,(b)不会产生垃圾垃圾?
我可以用forEach()调用来做到这一点,混合旧的&新的方法......所以我至少可以利用流,但“优化”钙/滤波器/添加以古老的方式。有一个很好,简单,优雅的解决方案。帮我看到了光明......