简体   繁体   English

如何在Hashtable上进行迭代和比较 <String, Map<String, Set<String> &gt;&gt;在Java中

[英]how to iterate and compare over Hashtable<String, Map<String, Set<String>>> in java

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>>> 上面的格式为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. 我想比较一下active-csr-HA-profile的sapd-out是否与standby-csr-HA-profile的键之一相同。 So compare each key of active-csr-HA-profile to each key of standby-csr-HA-profile. 因此,将active-csr-HA配置文件的每个密钥与standby-csr-HA配置文件的每个密钥进行比较。

I looked some similar questions but what i am working out is not solving the purpose. 我看了一些类似的问题,但我正在解决的问题并未解决。

As already mentioned in the comments, the Hashtable is considered obsolete. 正如评论中已经提到的, Hashtable被认为已过时。 Its replacement is HashMap . 替换为HashMap If you wish make HashMap synchronized the same way the Hashtable does, use the Collections::synchronizedMap decorator on it. 如果希望以与Hashtable相同的方式使HashMap同步,请在其上使用Collections::synchronizedMap装饰器。

The structure of your Hashtable looks a bit unclear. Hashtable的结构看起来有点不清楚。 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. .filter(i -> i.getValue().containsAll(..)过滤Set<String>值包含所有必需的String的实体。
  • .forEach(..) gives a consumer performing an action over all the matching results. .forEach(..)使使用者对所有匹配结果执行操作。

In case you need the boolean representing whether the match has occurred or not, do: 如果您需要表示匹配是否发生的boolean ,请执行以下操作:

boolean matches = map.get(..).entrySet().stream().filter(..).findFirst().isPresent();

As mentioned in the comments, HashTable is a debatable choice. 如评论中所述, HashTable是值得商a的选择。 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. 我假设您的表中可能会有更多的条目,而您想比较特定的条目。

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. 正如其他人所说,与Hashtable相比,大多数情况下HashMap更可取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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