java - 如何使用computeIfAbsent()在HashMap中缓存数据?

标签 java collections java-8

我有单独的目录,其中包含具有类属性的文件和具有嵌入对象类型属性的目录。 首先加载类的属性,然后 loadEmbeddedTypeProps() 方法遍历类的字段,如果找到某种类型的字段(我在下面的示例中使用枚举),则加载属性类型以及来自另一个目录的类型。最后,调用 mergeProperties() 方法合并该类及其嵌入类型的属性。

我决定在静态 cachedProperties HashMap 中缓存嵌入类型的属性。 如果它已经包含某个键的属性,那么我们从 cachedProperties 获取它们并与 locaProperties HashMap 合并。如果没有,我们将从文件下载属性(调用 loadPropsForType())。

逻辑按预期工作,但看起来 loadEmbeddedTypeProps() 方法中的代码可以通过使用 computeIfAbsent 方法进行改进。我最近开始尝试 lambda,但不确定这里如何实现。它也是使用computeIfAbsent的合适地点吗?

private static Map<String, Map<String, Properties>> cachedProperties = new HashMap<>();

            private Map<String, Properties> loadEmbeddedTypeProps(Class myClass) {
                Map<String, Properties> localProperties = new HashMap<>();
                Arrays.stream(myClass.getFields())
                        .filter(field -> field.getType().isAssignableFrom(Enumerated.class))
                        .forEach(field -> {
                            String fieldName = field.getType().getSimpleName();
                            String enumTypeName = StringUtils.uncapitalize(fieldName);
                            try {
                                if (cachedProperties.containsKey(enumTypeName)) {
                                 // properties for enumerated type are already in cache
                                    Map<String, Properties> propertiesFromCache = cachedProperties.get(enumTypeName);
                                    mergeProperties(propertiesFromCache, localProperties);
                                } else {
                                // properties for enumerated type are not cached yet
                                    Map<String, Properties> loadEnumProperties = loadPropsForType(enumTypeName);
                                    cachedProperties.put(enumTypeName, loadEnumProperties);
                                    mergeProperties(loadEnumProperties, localProperties);
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });
                return localProperties;
            }

最佳答案

您可以使用computeIfAbsent ,但是因为您不能从 Function<...> 抛出已检查的异常你必须把 try catch在 lambda 内部,您传递给 computeIfAbsent .

.forEach(field -> {
    String fieldName = field.getType().getSimpleName();
    String enumTypeName = StringUtils.uncapitalize(fieldName);
    Map<String, Properties> enumProperties 
        = cachedProperties.computeIfAbsent(enumTypeName, key -> {
                try {
                    return loadPropsForType(key);
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            });
    mergeProperties(enumProperties, localProperties);
});

返回null告诉 computeIfAbsent 不应进行映射。

If the mapping function returns null, no mapping is recorded.

因此,如果抛出异常,该字段基本上会被忽略。请注意,返回的 enumProperties也将是null ,所以你必须在mergeProperties中处理这个问题。 .

关于java - 如何使用computeIfAbsent()在HashMap中缓存数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48014590/

相关文章:

java - HPE UFT 干扰计算机中的 java 配置

java - 使用 Collections.sort 对对象 ArrayList 进行排序

java - 手动链接 GroupBy 收集器

java - 增加 MAC OSX 10.12 中的 JVM 最大堆大小

java - Do-While 循环在 Java 中无法正常运行

java - 获取 Sprite 与屏幕的距离

java - Android - 我们在 HashMap<MyEnum, String> 中使用 enum 作为键代替 String 是否合适?

c# - 无法隐式转换类型 'System.Collections.Generic.IEnumerable Cast 错误

java-8 - Kotlin 中的 javax.time

java-8 - DoubleSummaryStatistics 中的 sum 与 simpleSum 与 sumCompensation?拥有它们有什么重要意义?