I have this code working with a for loop and steam, but I was wondering I can improve it using two streams. Here I want to replace the for loop with a stream and would like to get a list of String that the method returns.
public class City {
final int x;
final int y;
final String name;
public City(String name, int x, int y) {
this.name = name;
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public String getName() {
return name;
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Test {
public static boolean cityFilter(City city, City c) {
return !city.getName().equals(c.getName()) && (city.getX()==c.getX() || city.getY()==c.getY())?true:false;
}
public static int compareCities(City c, City c1, City c2) {
int dis1 = Math.abs(c.getX() - c1.getX()) Math.abs(c.getY() - c1.getY());
int dis2 = Math.abs(c.getX() - c2.getX()) Math.abs(c.getY() - c2.getY());
return dis1==dis2?c.getName().compareTo(c2.getName()):dis1-dis2;
}
public static List<String> filterAndFindCities(List<String> c, List<Integer> x, List<Integer> y, List<String> q) {
Map<String, City> cityMap = IntStream.range(0, c.size()).boxed().collect(Collectors.toMap(c::get, i-> new City(c.get(i), x.get(i), y.get(i))));
List<String> rst = new ArrayList<String>();
//====How can I replace this for loop with a stream and get a list of String?===
for (String s : q) {
City givenCity = cityMap.get(s);
City nearest = cityMap.values().stream().filter(p -> cityFilter(givenCity, p))
.sorted((c1, c2) -> compareCities(givenCity, c1, c2))
.findFirst().orElse(null);
String nearestCity = nearest != null ? nearest.getName() : "EMPTY";
rst.add(nearestCity);
}
return rst;
}
}
CodePudding user response:
I was able to find a quick and dirty solution, of course not the best, but sure I can improve this.
public static List<String> filterAndFindCities(List<String> c, List<Integer> x, List<Integer> y, List<String> q) {
Map<String, City> cityMap = IntStream.range(0, c.size()).boxed()
.collect(Collectors
.toMap(c::get, i -> new City(c.get(i), x.get(i),
y.get(i))));
return q.stream()
.map(name ->cityMap.values().stream()
.filter(p -> cityFilter(cityMap.get(name), p))
.sorted((c1, c2) -> compareCities(cityMap.get(name), c1, c2))
.findFirst().orElse(null))
.map(p->p!=null?p.getName():"EMPTY")
.collect(Collectors.toList());
}