1

I have a structure like below ,

Key: active-csr-HA-profile & Value: {sapd-outside=[outside], sapd-extra4=[extra4], sapd-extra3=[extra3], sapd-inside=[inside]}
Key = sapd-outside, Value = [outside]
Key = sapd-extra4, Value = [extra4]
Key = sapd-extra3, Value = [extra3]
Key = sapd-inside, Value = [inside]
Key: standby-csr-HA-profile & Value: {sapd-outside=[outside], sapd-extra4=[extra4], sapd-extra3=[extra3], sapd-inside=[inside]}
Key = sapd-outside, Value = [outside]
Key = sapd-extra4, Value = [extra4]
Key = sapd-extra3, Value = [extra3]
Key = sapd-inside, Value = [inside]

the above if of format Hashtable<String, Map<String, Set<String>>>

I want to compare if sapd-outside of active-csr-HA-profile is same as one of the keys of standby-csr-HA-profile. So compare each key of active-csr-HA-profile to each key of standby-csr-HA-profile.

I looked some similar questions but what i am working out is not solving the purpose.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
nisha
  • 703
  • 2
  • 14
  • 28
  • That doesn't make sense. Hashtable is a legacy interface you shouldn't be using in the first place. Why not a `Map`? – GhostCat Aug 24 '18 at 12:05
  • 2
    Beyond that: when you have "not working" code, then provide a [mcve]. Also *link* to the questions you read before. We have no idea what research you did, and what helped you , and what not. – GhostCat Aug 24 '18 at 12:06
  • 1
    @GhostCat `Hashtable` is not an interface; it is an implementation of the `Map` interface and tries to address concurrency affairs. But indeed, modern code should, but only when synchronization is desired, use `Collections.synchronizedMap` rather than the `Hashtable` class. [See here](https://stackoverflow.com/questions/9536077/when-should-i-use-a-hashtable-versus-a-hashmap). – MC Emperor Aug 24 '18 at 12:13
  • "interface" as in "something to program with", not in the class vs interface sense ;-) Beyond that, Hashtable exists since Java 1.0 ... and yes, it later became a map, but a hashtable of maps is just ... wrong. – GhostCat Aug 24 '18 at 12:34

3 Answers3

1

As already mentioned in the comments, the Hashtable is considered obsolete. Its replacement is HashMap. If you wish make HashMap synchronized the same way the Hashtable does, use the Collections::synchronizedMap decorator on it.

The structure of your Hashtable looks a bit unclear. I guess the following structure matches your one the best and I base my solution on it.

Hashtable<String,  Map<String, Set<String>>> map = new Hashtable<>();

Map<String, Set<String>> activeCsrHAProfile = new HashMap<>();
activeCsrHAProfile.put("sapd-outside", new HashSet<>(Arrays.asList("outside")));
activeCsrHAProfile.put("sapd-extra4", new HashSet<>(Arrays.asList("extra4")));
activeCsrHAProfile.put("sapd-extra3", new HashSet<>(Arrays.asList("extra3")));
activeCsrHAProfile.put("sapd-inside", new HashSet<>(Arrays.asList("inside")));

Map<String, Set<String>> standbyCsrHAProfile = new HashMap<>();
standbyCsrHAProfile.put("sapd-outside", new HashSet<>(Arrays.asList("outside")));
standbyCsrHAProfile.put("sapd-extra4", new HashSet<>(Arrays.asList("extra4")));
standbyCsrHAProfile.put("sapd-extra3", new HashSet<>(Arrays.asList("extra3")));
standbyCsrHAProfile.put("sapd-inside", new HashSet<>(Arrays.asList("inside")));

map.put("active-csr-HA-profile", activeCsrHAProfile);
map.put("standby-csr-HA-profile", standbyCsrHAProfile);

In case my structure differs a bit from yours, there would be no problem to amend the solution in order to match your structure - the principle is the same.

Set<String> sapdOutsideOfActiveCsrHAProfile = map.get("active-csr-HA-profile")
                                                 .get("sapd-outside");

map.get("standby-csr-HA-profile").entrySet()
   .stream()
   .filter(i -> i.getValue().containsAll(sapdOutsideOfActiveCsrHAProfile))
   .forEach(e -> System.out.println("Found at: " + 
       "key=" + e.getKey() + ", value=" + e.getValue()));
  • .filter(i -> i.getValue().containsAll(..) filters those entris which values Set<String> contains all of the required Strings.
  • .forEach(..) gives a consumer performing an action over all the matching results.

In case you need the boolean representing whether the match has occurred or not, do:

boolean matches = map.get(..).entrySet().stream().filter(..).findFirst().isPresent();
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
1

As mentioned in the comments, HashTable is a debatable choice. Regardless of the implementation you choose, you could create your own class to manage the messy stuff:

public class CustomMap extends Hashtable<String, Map<String, Set<String>>> {

    public CustomMap() {
        super();
    }

    public boolean compareEntries(String key1, String key2) {
        if (!this.containsKey(key1) || !this.containsKey(key2) || this.get(key1).size() != this.get(key2).size())
            return false;

        for (String innerKey : this.get(key1).keySet()) {
            if (!this.get(key2).containsKey(innerKey)) {
                return false;
            }

            final Set<String> setA = this.get(key1).get(innerKey);
            final Set<String> setB = this.get(key2).get(innerKey);
            if (!setA.containsAll(setB) || !setB.containsAll(setA)) {
                return false;
            }
        }

        return true;
    }
}

I took the assumption there could be more entries in your table and you'd want to compare specific entries.

Pierre
  • 111
  • 1
  • 4
0

You can iterate through a map with its entry set:

    Hashtable<String,  Map<String, Set<String>>> table = new Hashtable();

    for (Map.Entry<String, Map<String, Set<String>>> entry : table.entrySet()) {
        String key = entry.getKey();
        Map<String, Set<String>> map = entry.getValue();

        for (Map.Entry<String, Set<String>> mapEntry : map.entrySet()) {
            String mapKey = mapEntry.getKey();
            Set<String> set = mapEntry.getValue();

            for (String text : set) {
                // ...
            }
        }           
    }

Nesting sets inside maps inside maps makes the code hard to read though, you might want to use specialized objects instead.

As others have said, in most cases HashMap is preferrable compared to an Hashtable.

Guillaume
  • 14,306
  • 3
  • 43
  • 40