首页 > 解决方案 > 比较两个 Treemaps 的内容

问题描述

我有两个要比较的 TreeMap。我目前把它写下来如下,但我觉得这可以更有效地写出来。我尝试查看比较器,但我认为这不能用于我的用例。

这些映射是 Treemap,因为键必须不区分大小写。

public void theseRulesAreTheSame() {
    List<String> failures = new ArrayList<>();

    TreeMap<String, NSG> configNsgs = platformConfiguration.getAzure().nsgs();
    configNsgs.forEach((name, nsg) -> {
      assertThat(azureAdapter.doesNsgExistInAzure(name))
          .as("Unable to find network security group " + name + " in Azure.").isTrue();

      List<SecurityRulesItem> configSecurityRules = nsg.getSecurityRules();
      TreeMap<String, Object> azureSecurityRules = azureAdapter
          .getSecurityRulesForNsg(name);

      assertThat(configSecurityRules.size())
          .as("The nymber of security rules in Azure does not correspond to the number of security rules in the configuration!")
          .isEqualTo(azureSecurityRules.size());

      configSecurityRules.forEach(configSecurityRule -> {
        SecurityRuleInner azureSecurityRule = (SecurityRuleInner) azureSecurityRules
            .get(configSecurityRule.getRuleName());

        logger.info(
            "Checking security rule " + configSecurityRule.getRuleName()
                + " in network security group "
                + nsg.getName());

        if (null == azureSecurityRule) {
            logFailure(failures, null, configSecurityRule.getRuleName());
        } else {
          if (!azureSecurityRule.access().toString().equalsIgnoreCase(configSecurityRule.getAccess())) {
            logFailure(failures, configSecurityRule.getAccess(), azureSecurityRule.access());
          }
          if (!azureSecurityRule.destinationAddressPrefix().equalsIgnoreCase(configSecurityRule.getDestinationAddressPrefix())) {
            logFailure(failures, configSecurityRule.getDestinationAddressPrefix(), azureSecurityRule.destinationAddressPrefix());
          }
          if (!azureSecurityRule.destinationPortRange().equalsIgnoreCase(configSecurityRule.getDestinationPortRange())) {
            logFailure(failures, configSecurityRule.getDestinationPortRange(), azureSecurityRule.destinationPortRange());
          }
          if (!azureSecurityRule.sourceAddressPrefix().equalsIgnoreCase(configSecurityRule.getSourceAddressPrefix())) {
            logFailure(failures, configSecurityRule.getSourceAddressPrefix(), azureSecurityRule.sourceAddressPrefix());
          }
          if (!azureSecurityRule.sourcePortRange().equalsIgnoreCase(configSecurityRule.getSourcePortRange())) {
            logFailure(failures, configSecurityRule.getSourcePortRange(), azureSecurityRule.sourcePortRange());
          }
          if (!azureSecurityRule.protocol().toString().equalsIgnoreCase(configSecurityRule.getProtocol())) {
            logFailure(failures, configSecurityRule.getProtocol(), azureSecurityRule.protocol());
          }
          if (!azureSecurityRule.direction().toString().equalsIgnoreCase(configSecurityRule.getDirection())) {
            logFailure(failures, configSecurityRule.getDirection(), azureSecurityRule.direction());
          }
        }
      });
    });
    if (!failures.isEmpty()) {
      Assertions.fail(
          "Error(s) detected while comparing the network security groups between Azure and the config. Failures: "
              + failures);
    }
  }

提前致谢

标签: javacollectionstreemap

解决方案


如果我们有这两种类型AzureSecurityRuleConfigSecurityRule我们可以像这样使比较不那么冗长:

 BiConsumer<AzureSecurityRule, ConfigSecurityRule>  compareField(Function<AzureSecurityRule,String> f1, Function<ConfigSecurityRule> f2) {
return (az, cf) -> {
    if !f1.apply(az).equalsIgnoreCase(f2.apply(cf)) {
      logFailure(failure, f2.apply(cf), f1.apply(az));
    }
  }
}
...
List.of(
  compareField(az -> az.access().toString(), cf -> cf.getAccess()),
  compareField(az -> az.destinationAddressPrefix(), cf -> cf.getDestinationAddressPrefix()),
  ...
).forEach(cf -> cf.accept(azureSecurityRule, configSecurityRule));

推荐阅读