2017-12-28 15 views
0

나는 임베디드 오브젝트 유형에 대한 특성을 가진 클래스 및 디렉토리에 대한 특성을 가진 파일을 포함하는 별도의 디렉토리를 가지고 있습니다. 클래스의 첫 번째 속성이로드 된 다음 loadEmbeddedTypeProps() 메서드가 클래스 필드를 통과하고 특정 형식의 필드 (아래 예에서 열거 됨)가 발견되면 다른 디렉터리의 형식에 대해서도 속성이로드됩니다. 그리고 마지막으로 클래스와 그 임베디드 타입에 대한 속성이 병합되어 mergeProperties() 메서드가 호출됩니다.HashMap에서 데이터를 캐싱하기 위해 computeIfAbsent()를 사용하는 방법은 무엇입니까?

정적 인 cachedProperties HashMap에 포함 된 유형의 속성을 캐시하기로 결정했습니다. 이미 특정 키에 대한 속성이 포함되어있는 경우 cachedProperties에서 가져오고 locaProperties HashMap과 병합합니다. 그렇지 않은 경우 파일에서 속성을 다운로드합니다 (loadPropsForType()가 호출 됨).

로직은 예상대로 작동하지만 loadEmbeddedTypeProps() 메서드의 코드가 computeIfAbsent 메서드를 사용하여 향상 될 수 있습니다. 나는 최근에 람다 (lambdas)에 대한 실험을 시작했으며 이것이 람다 (lambdas)가 어떻게 구현 될지 확신하지 못했습니다. 또한 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; 
      } 
+0

'loadPropsForType'가'IOException'을 던집니까? –

+0

@JornVernee 예,이 메소드는'IOException'을 throw합니다. – samba

답변

1

당신은 computeIfAbsent를 사용할 수 있지만이 Function<...>에서 확인이 끝난 예외를 던질 수 없기 때문에 당신은 당신이 computeIfAbsent에 전달 람다 내부의 try catch을 넣어야 할 것입니다.

.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을 알려줍니다.

매핑 함수가 null을 반환하면 매핑이 기록되지 않습니다.

따라서 예외가 발생하면 기본적으로 필드는 무시됩니다. 반환 된 enumPropertiesnull이므로 mergeProperties에서 처리해야합니다.

1

예, 여기서 computeIfAbsent()이 적합합니다.

Map<String, Properties> properties = 
     cachedProperties.computeIfAbsent(enumTypeName, this::loadPropsForType); 
mergeProperties(properties, localProperties); 

loadPropsForType 가정하면 바깥 쪽 클래스의 인스턴스 방법 : 다음과 같이 사용할 수 있습니다. 그것이 무엇이든간에, 메소드 참조를 적절하게 대체하십시오. 여기서 메소드 참조의 유형은 computeIfAbsent의 설명서에 따라 Function<? super String, ? extends Map<String, Properties>>의 부속 유형입니다.

관련 문제