Как перебрать и сравнить Hashtable <String, Map <String, Set <String>>> в Java - PullRequest
0 голосов
/ 24 августа 2018

У меня есть структура, как показано ниже,

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]

выше, если в формате Hashtable<String, Map<String, Set<String>>>

Я хочу сравнить, если sapd-снаружи active-csr-HA-профилятакой же, как один из ключей профиля standby-csr-HA.Поэтому сравните каждый ключ профиля active-csr-HA с каждым ключом профиля standby-csr-HA.

Я посмотрел несколько похожих вопросов, но то, над чем я работаю, не решает задачу.

Ответы [ 3 ]

0 голосов
/ 24 августа 2018

Как уже упоминалось в комментариях, Hashtable считается устаревшим.Его замена составляет HashMap.Если вы хотите, чтобы HashMap синхронизировался так же, как Hashtable, используйте декоратор Collections::synchronizedMap.

Структура вашего Hashtable выглядит немного неясной.Я предполагаю, что следующая структура лучше всего соответствует вашей, и на этом я основываю свое решение.

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);

В случае, если моя структура будет немного отличаться от вашей, не будет проблем с исправлением решения для соответствия вашей структуре - принцип тот же.

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(..) фильтрует те энтрисы, значения которых Set<String> содержат все необходимые строки.
  • .forEach(..) дает потребителю выполнение действия со всеми результатами сопоставления.

Если вам нужен boolean, представляющий, произошло ли совпадение или нет, выполните:

boolean matches = map.get(..).entrySet().stream().filter(..).findFirst().isPresent();
0 голосов
/ 24 августа 2018

Как уже упоминалось в комментариях, HashTable является дискуссионным выбором.Независимо от выбранной вами реализации, вы можете создать свой собственный класс для управления беспорядочными вещами:

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;
    }
}

Я предположил, что в вашей таблице может быть больше записей, и вы захотите сравнить конкретные записи.

0 голосов
/ 24 августа 2018

Вы можете выполнять итерацию по карте с ее набором записей:

    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) {
                // ...
            }
        }           
    }

Вложенные наборы внутри карт внутри карт затрудняют чтение кода, хотя вместо этого вы можете захотеть использовать специализированные объекты.

Как уже говорили другие, в большинстве случаев HashMap предпочтительнее, чем Hashtable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...