简体   繁体   中英

Need a Fresh pair of Eyes to Work Out the Logic Behind Comparing Values in a Map of Maps

Problem

Data is in the format:

Map<String, Map<String, Integer>>

Which looks something like this:

{"MilkyWay": {"FirstStar" : 3, "SecondStar" : 9 .... }, "Andromeda": {"FirstStar" : 10, "SecondStar" : 9 .... } }

I want to compare the Star values in a quick loop, so I'd like to compare the integer value of FirstStar in MilkyWay and Andromeda and have it return true or false if the values are the same or not. Since this Map of Maps is huge.

My Attempt

I'd like to do it something like:

//GalaxyMap<String, <Map<String, Integer>>

            for (Map<String, Integer> _starMap : GalaxyMap.values())
            {
                for (String _starKey : _starMap.keySet()){
                    //Can't quite think of the correct logic... and I'm tired...
                }

            }

I'd like to keep it as short as possible... I've been staring at this for a while and I'm going in circles with it.

EDIT

Outer keys differ, Inner keys are the same

Also since this is a response from a server, I don't know the size it's going to be

Why does this need to be a map. If you're always using "FirstStar", "SecondStar" etc, as your keys, then why not make it a list instead..

Map<String, List<Integer>>

Then you can do something like:

public boolean compareGalaxyStar(String galaxyName, String otherGalaxyName, int star) {
    List<Integer> galaxyStars = galaxyMap.get(galaxyName);
    List<Integer> otherGalaxyStars = galaxyMap.get(otherGalaxyName);

    return galaxyStars.get(star) == otherGalaxyStars.get(star);
}

NOTE : You need to do some validation to make sure the input is correct.

To implement this for all stars, it is not much different.

if(galaxyStars.size() == otherGalaxyStars.size()) {
    for(int x = 0; x < galaxyStars.size(); x++) {
        // Perform your comparisons.
        if(galaxyStars.get(x) != otherGalaxyStars.get(x)) {
             // Uh oh, unequal.
             return false;
        }
    }
}

If the structure of the inner maps also could differ, you should do something like that:

static boolean allStarValuesEqual(Map<String, Map<String, Integer>> galaxies) {
    Map<String, Integer> refStars = null;
    for (Map<String, Integer> galaxy : galaxies.values()) {
        if (refStars == null) {
            refStars = galaxy;
        } else {
            for (Entry<String, Integer> currentStar : galaxy.entrySet()) {
                if (!currentStar.getValue().equals(refStars.get(currentStar.getKey()))) {
                    return false;
                }
            }
        }
    }
    return true;
}

Please check below program along with output:

package com.test;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class CompareMapValues {
    private final static String FS = "FirstStar";
    private final static String SS = "SecondStar";
    private final static String MW = "MilkyWay";
    private final static String A = "Andromeda";

    public static void main(String[] args) {
        Map> map = new HashMap>();
        Map innerMap1 = new HashMap();
        innerMap1.put(FS, 3);
        innerMap1.put(SS, 9);
        Map innerMap2 = new HashMap();
        innerMap2.put(FS, 10);
        innerMap2.put(SS, 9);
        map.put(MW, innerMap1);
        map.put(A, innerMap2);
        Set set = map.keySet();
        for(String s: set) {
            Map outerMap = map.get(s);
            Set set2 = map.keySet();
            for(String s2: set2) {
                Map innerMap = map.get(s2);
                if(!s2.equals(s)) {
                    Set set3 = outerMap.keySet();
                    for(String s3: set3) {
                        int i1 = outerMap.get(s3);
                        Set set4 = innerMap.keySet();
                        for(String s4: set4) {
                            int i2 = innerMap.get(s3);
                            if(s3.equals(s4) && i1==i2) {
                                System.out.println("For parent " + s + " for " + s3 + " value is " + i1);
                            }
                        }
                    }
                }
            }
        }
    }
}
//Output:
//For parent Andromeda for SecondStar value is 9
//For parent MilkyWay for SecondStar value is 9

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM