Search code examples
javaalgorithmjava-8java-streamtreemap

Create a TreeMap from nested list using Java Streams


Given: I have List<List<Integer>> locations which is coordinates of a location. For example Place A: (2,4), Place B: (5,4), Place C: (10,9), Place D: (2,4). So my locations would contain of list of lists. I am unable to change this format.

The cost to go to a specific location is the square root of the sum of the coordinates. So to go to the cost is Place A = Math.sqrt(2 + 4), cost to go to Place B = Math.sqrt(5 + 4) and so on.

Output: What I'm trying to get is a list of the least 'cost' of all the locations. The requirement for the return is List<List<Integer>> nearestLocations. What I did is I'm trying to create a TreeMap<Double, List<List<Integer>>

Question my question is how do I convert the convert the below using Java 8 streams?

 List<List<Integer>> findNearestLocation(int total, List<List<Integer>> allLocations, int size) {
        ArrayList<List<Integer>> results = new ArrayList<>();
        TreeMap<Double, List<Integer>> map = new TreeMap<>();
        for (int i = 0; i < total && i < allLocations.size(); i++) {
            List<Integer> list = allLocations.get(i);
            double l = 0.0;
            for (Integer x : list) {
                l += x * x;
            }
            map.put(Math.sqrt(l), list);
        }
        if (map.size() > 0) {
            for (int get = 0; get < size; get++) {
                results.add(map.get(map.firstKey()));
                map.remove(map.firstKey());
            }

        }
        return results;
    }

Solution

  • Your Map is actually Map<Double, List<Integer>>

    Your current code return just Map if you want TreeMap you need:

        TreeMap<Double, List<List<Integer>>> x = locations.stream().collect(
                Collectors.groupingBy((List<Integer> b) -> {
                            double d = b.stream().mapToDouble(i -> i.doubleValue()).sum();
                            return Math.sqrt(d);
                        },
                        TreeMap::new,
                        Collectors.toList()));
    

    PS: You distance is not usual euclidean distance. To make it so you need i -> i.doubleValue() * i.doubleValue()