javaarraylistcollectionshashmapkruskals-algorithm

How do i create an arraylist of values from a nested HashMap in java?


I have written my code using a nested HashMap and i'm trying to figure out how to put all values pointed by the key of the inner map into an ArrayList, in order to properly sort it. My map looks like this:

HashMap<String, HashMap<String, Double>> vlist;

My idea was to create another HashMap with same key and value of the inner map shown before, then populate it in this way.

HashMap<String, Double> vlistValues = new HashMap<>(vlist.values());

I get a compilation error, and i can figure out that the compiler doesn't know that the value of my outer map is a map itself, but reading the hashmap documentation i didn't find a method that fits my situation.

Basically i want to put all the values of the inner map declared hereHashMap<String ,HashMap<String, Double>> vlist; to a list like thisArrayList<Double> listOfValues;

If it wasn't clear i'm totally new to programming :-)

I'll show an example: My map HashMap<String, Hashmap<String,Double>> represents the adjacency list of a weighted graph. I need to sort all the edges (as i'm trying to implement Kruskal's algorithm) and my idea was to put all the weights in an list doing something like this:

ArrayList<String> vertexList; //all the vertices of the graph
ArrayList<Double> weights; 
HashMap<String, String> orderedEdges = new HashMap<>(); //here i put ordered edges
double min = Collections.min(weights); //i use this double to keep track of the minimum element in weights

  for(String vertex1 : vertexlist){
    makeSet(vertex1);
    for(String vertex2 : ajacents(vertex1)){
      if(getEdgeWeight(v1,v2) <= min){ //method "getEdgeWeight" is to retrieve weight of an edge
        orderedEdges.put(v1,v2);
        min = getEdgeWeight(v1,v2) 
        weights.remove(min) //i'm not sure this line is correct
      }
    }
  }

Looking at some pseudo-code online i saw that it is able to make the disjoint sets and ordering the edges in the same for-loop. Probably my code is not efficent but i really don't know how to sort the edges without visiting all the graph. Ps i cannot use a priority queue but i perfectly know that what i'm trying to do is something similar


Solution

  • So you said:

    Basically i want to put all the values of the inner map declared here HashMap<String ,HashMap<String, Double>> vlist; to a list like this ArrayList<Double> listOfValues

    Here is the sample hashMap.

          Map<String, Map<String, Double>> mm = Map.of("A",
                Map.of("R", 1.2, "S", 3.4, "T", 3.8),
                "B",
                Map.of("S", 9.8, "V", 2.8),
                "Z",
                Map.of("P", 22.3));
    
          System.out.println(mm);
    

    Here's the map.

    {Z={P=22.3}, B={S=9.8, V=2.8}, A={T=3.8, S=3.4, R=1.2}}

    To convert to a List of doubles you can do this. Get a stream of the values (which are the inner maps), and then combine all the values in those maps into a common stream via a flatMap and then collect to a List.

          List<Double> dubs =
                mm.values().stream().flatMap(k -> k.values().stream()).collect(
                      Collectors.toList());
    
          System.out.println(dubs);
    

    Here's the list.

    [22.3, 9.8, 2.8, 3.8, 3.4, 1.2]

    If you want a Map<String, List<Doubles>> where the String is the key of the outer Map you can do this. Create a stream of entrySet of the outer map and pass it to a collector. The collector creates a map using the outer maps key and then takes the values of the inner map (which is a collection) and passes them as an argument to ArrayList<> to create a List.

      Map<String, List<Double>> mapOfDubs =
            mm.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(),
                  e -> new ArrayList<>(e.getValue().values())));
    
      System.out.println(mapOfDubs);
    

    Here's the map.

    {A=[1.2, 3.4, 3.8], B=[2.8, 9.8], Z=[22.3]}