Collections.unmodifiableMap()的理解

本文详细介绍了如何使用Java中的Collections.unmodifiableMap方法创建不可修改的映射,并展示了该方法的具体应用实例。同时,文章还探讨了不可修改映射与原始映射之间的关系及其对可变对象的影响。

照常,先来看看Collections.unmodifiableMap()的API:

unmodifiableSortedMap

public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
返回指定有序映射的不可修改视图。此方法允许模块为用户提供对内部有序映射的“只读”访问。在返回的有序映射上执行的查询操作将“读完”指定的有序映射。试图修改返回的有序映射(无论是直接修改、通过其 collection 视图修改,还是通过其 subMap、 headMap或 tailMap视图修改)将导致抛出 UnsupportedOperationException。
如果指定的有序映射是可序列化的,则返回的有序映射也将是可序列化的。

参数:
m - 将为其返回一个不可修改视图的有序映射。
返回:
指定有序映射的不可修改视图。
可能API中的解释不太好理解,没关系,看一个例子你就明白了:

package go.jacob.day729;
 
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
 
public class Demo5 {
   
   
	public static void main(String[] args) {
   
   
		Map<Integer,StringBuilder
D:\Program Files\elasticsearch-8.9.0\bin>elasticsearch-setup-passwords.bat interactive 09:23:57.180 [main] WARN org.elasticsearch.deprecation.common.settings.Settings - data_stream.dataset="deprecation.elasticsearch" data_stream.namespace="default" data_stream.type="logs" elasticsearch.event.category="settings" event.code="keystore.password" message="[keystore.password] setting was deprecated in Elasticsearch and will be removed in a future release." Exception in thread "main" org.elasticsearch.ElasticsearchSecurityException: failed to load SSL configuration [xpack.security.transport.ssl] - cannot specify both [keystore.secure_password] and [keystore.password] at org.elasticsearch.xpack.core.ssl.SSLService.lambda$getSSLConfigurations$4(SSLService.java:550) at java.base/java.util.HashMap.forEach(HashMap.java:1429) at java.base/java.util.Collections$UnmodifiableMap.forEach(Collections.java:1553) at org.elasticsearch.xpack.core.ssl.SSLService.getSSLConfigurations(SSLService.java:542) at org.elasticsearch.xpack.core.ssl.SSLService.<init>(SSLService.java:147) at org.elasticsearch.xpack.core.security.CommandLineHttpClient.execute(CommandLineHttpClient.java:149) at org.elasticsearch.xpack.core.security.CommandLineHttpClient.execute(CommandLineHttpClient.java:112) at org.elasticsearch.xpack.security.authc.esnative.tool.SetupPasswordTool$SetupCommand.checkElasticKeystorePasswordValid(SetupPasswordTool.java:340) at org.elasticsearch.xpack.security.authc.esnative.tool.SetupPasswordTool$InteractiveSetup.execute(SetupPasswordTool.java:203) at org.elasticsearch.common.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:54) at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:85) at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:94) at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:85) at org.elasticsearch.cli.Command.main(Command.java:50) at org.elasticsearch.launcher.CliToolLauncher.main(CliToolLauncher.java:64) Caused by: org.elasticsearch.common.ssl.SslConfigException: cannot specify both [keystore.secure_password] and [keystore.password]
06-11
这个代码有什么问题? @Override public void checkNotificationRuleDifferences() { Set<String> persistanceNotificationTypeSet = new HashSet<>(); Set<String> multiLanguageNotificationTypeSet = new HashSet<>(); for (Set<String> persistanceSet : msgProps.getAppCategoryToMsgTypeMap().values()) { persistanceNotificationTypeSet.addAll(persistanceSet); } for (Set<String> multiLanguageSet : msgProps.getAppCategoryToMultiLanguageMsgTypeMap().values()) { multiLanguageNotificationTypeSet.addAll(multiLanguageSet); } Map<String, Properties> propsByAppCategory = new HashMap<>(); // 按 appCategory 分组的 key 来源文件映射 Map<String, Map<String, String>> keySourceMapByAppCategory = new HashMap<>(); // 文件名前缀提取的正则缓存为常量 Pattern APP_CATEGORY_PATTERN = Pattern.compile("^([a-z0-9]+)"); Map<String, String> MANUAL_APP_CATEGORY_MAP; Map<String, String> map = new HashMap<>(); map.put("alertMapping.properties", "common"); map.put("decoAlertMapping.properties", "aria"); map.put("omadaGuardAlertMapping.properties", "omadaGuard"); MANUAL_APP_CATEGORY_MAP = Collections.unmodifiableMap(map); try { // 1. 加载并按 appCategory 分组 loadPropertiesGroupedByAppCategory(propsByAppCategory, keySourceMapByAppCategory, MANUAL_APP_CATEGORY_MAP, APP_CATEGORY_PATTERN); // 2. 分页参数配置 int pageNum = 1; int pageSize = 100; List<NotificationRulePO> currentPageRules; Set<String> combinedNotificationType = new HashSet<>(); Map<String, NotificationRulePO> notificationType2NotificationRuleMap = new HashMap<>(); long count = notificationRuleDAO.notificationRuleCount(); long pageCount = count / pageSize + 1; // 3. 使用现有的分页查询函数 do { // 调用分页查询函数 currentPageRules = notificationRuleDAO.pageFindNotificationRule(pageNum, pageSize); // 4. 处理当前页数据(完全保留原有逻辑) for (NotificationRulePO rule : currentPageRules) { String appCategory = StringUtils.defaultString(rule.getAppCategory(), ""); Properties props = propsByAppCategory.get(appCategory); Map<String, String> keySourceMap = keySourceMapByAppCategory.get(appCategory); boolean isValidNotificationRule = validateRuleInputs(rule, appCategory, propsByAppCategory, keySourceMapByAppCategory); if (!isValidNotificationRule) { continue; } String notificationType = StringUtils.defaultString(rule.getNotificationType(), ""); notificationType2NotificationRuleMap.put(notificationType, rule); List<org.bson.Document> copyWritings = Optional .ofNullable(rule.getCopywritingList()) .orElse(Collections.emptyList()); for (org.bson.Document doc : copyWritings) { if (doc == null) { continue; } String lang = StringUtils.defaultString(doc.getString("language"), ""); if (StringUtils.isBlank(lang)) { continue; } String mongoTitle = doc.getString("title"); String mongoBody = doc.getString("body"); String titleKey = notificationType + ".title." + lang; String bodyKey = notificationType + ".body." + lang; String propTitle = findPropertyValue(props, titleKey); String propBody = findPropertyValue(props, bodyKey); // ===== Title 对比 ===== checkFieldMismatch(props, keySourceMap, propTitle, mongoTitle, "title", notificationType, lang); // ===== Body 对比 ===== checkFieldMismatch(props, keySourceMap, propBody, mongoBody, "body", notificationType, lang); } NotificationConfig config = rule.getConfig(); if (notificationType.contains("_")) { String[] str = notificationType.split("_"); if (appCategory.equalsIgnoreCase(AppCategoryEnum.VIGI.getValue()) || appCategory.equalsIgnoreCase(AppCategoryEnum.OMADAGUARD.getValue())) { notificationType = str[0]; } else if (str.length == 2) { String tempNotificationType = str[0]; rule = notificationType2NotificationRuleMap.get(tempNotificationType); if (rule == null) { rule = notificationType2NotificationRuleMap.get(notificationType); if (rule == null) { combinedNotificationType.add(notificationType); } } else { notificationType = tempNotificationType; } } else { combinedNotificationType.add(notificationType); continue; } } boolean persistanceRight; boolean persistanceActual = config.getEnablePersistent(); if (persistanceNotificationTypeSet.contains(notificationType)) { persistanceRight = true; } else { if (notificationType.equalsIgnoreCase("tpSimpleSetup")) { persistanceRight = false; } else { persistanceRight = appCategory.equalsIgnoreCase(AppCategoryEnum.TAPO.getValue()) || appCategory.equalsIgnoreCase(AppCategoryEnum.HALO.getValue()); } } if (persistanceActual != persistanceRight) { log.error("app:{} notification type:{} persistence is {}, right is {}", appCategory, notificationType, persistanceActual, persistanceRight); } if (multiLanguageNotificationTypeSet.contains(notificationType)) { log.info("----------------"); if (!Boolean.TRUE.equals(config.getSupportMultiLanguage())) { log.info("******************"); log.error("app:{} notification type:{} multiLanguage is error, right is true", appCategory, notificationType); } } else { if (!Boolean.FALSE.equals(config.getSupportMultiLanguage())) { log.error("app:{} notification type:{} multiLanguage is error, right is false", appCategory, notificationType); } } Integer ttl = msgPersistanceDayMap.get(notificationType); if (null == ttl) { if (config.getTtl() != 1) { log.error("notification type:{} ttl is error:{}, right is 1", notificationType, config.getTtl()); } } else { if (!ttl.equals(config.getTtl())) { log.error("notification type:{} ttl is error:{}, right is {}", notificationType, config.getTtl(), ttl); } } } pageNum++; } while (pageNum < pageCount); log.info(JacksonUtil.parseToStr(combinedNotificationType)); log.info("Notification copywriting difference check completed"); } catch (IOException e) { log.error("Failed to read properties files", e); } }
最新发布
11-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你不懂、、、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值