새로운 computeIfAbsent 함수를 어떻게 사용합니까?
나는 Map.computeIfAbsent 를 사용하고 싶지만 학부에서 람다 이후로 너무 오래되었습니다.
문서에서 거의 직접 : 작업을 수행하는 이전 방법의 예를 제공합니다.
Map<String, Boolean> whoLetDogsOut = new ConcurrentHashMap<>();
String key = "snoop";
if (whoLetDogsOut.get(key) == null) {
Boolean isLetOut = tryToLetOut(key);
if (isLetOut != null)
map.putIfAbsent(key, isLetOut);
}
그리고 새로운 방법 :
map.computeIfAbsent(key, k -> new Value(f(k)));
그러나 그들의 예에서 나는 "그것을 이해"하고 있지 않다고 생각합니다. 이것을 표현하는 새로운 람다 방식을 사용하도록 코드를 어떻게 변환할까요?
다음 코드가 있다고 가정합니다.
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
public static void main(String[] s) {
Map<String, Boolean> whoLetDogsOut = new ConcurrentHashMap<>();
whoLetDogsOut.computeIfAbsent("snoop", k -> f(k));
whoLetDogsOut.computeIfAbsent("snoop", k -> f(k));
}
static boolean f(String s) {
System.out.println("creating a value for \""+s+'"');
return s.isEmpty();
}
}
그러면 해당 키에 대한 값이 이미있는 creating a value for "snoop"
두 번째 호출 에서 메시지가 정확히 한 번만 표시됩니다 computeIfAbsent
. k
람다 표현은 k -> f(k)
바로지도가 값을 계산하기 위해 람다로 전달됩니다 키에 대한 placeolder (매개 변수)입니다. 따라서 예제에서 키는 함수 호출로 전달됩니다.
또는 다음과 같이 작성할 수 whoLetDogsOut.computeIfAbsent("snoop", k -> k.isEmpty());
있습니다. 도우미 메서드없이 동일한 결과를 얻을 수 있습니다 (하지만 디버깅 출력은 표시되지 않음). 또한 기존 메소드에 대한 간단한 위임이므로 더 간단합니다. whoLetDogsOut.computeIfAbsent("snoop", String::isEmpty);
이 위임은 매개 변수를 작성할 필요가 없습니다.
으로 가까운 예에 질문에 있으려면, 당신은 그것을 쓸 수 whoLetDogsOut.computeIfAbsent("snoop", key -> tryToLetOut(key));
(당신이 매개 변수의 이름을 여부를 중요하지 않습니다 k
또는 key
). 또는로 쓰는 whoLetDogsOut.computeIfAbsent("snoop", MyClass::tryToLetOut);
경우 tryToLetOut
입니다 static
또는 whoLetDogsOut.computeIfAbsent("snoop", this::tryToLetOut);
경우는 tryToLetOut
인스턴스 방법이다.
최근에 저도이 방법을 가지고 놀았습니다. 나는 방법을 사용하는 방법에 대한 또 다른 예시가 될 수있는 피보나치 수를 계산하는 메모 알고리즘을 작성했습니다.
우리는지도를 정의하고 기본 경우에 그것의 값을 넣어 시작할 수 있습니다, 즉, fibonnaci(0)
및 fibonacci(1)
:
private static Map<Integer,Long> memo = new HashMap<>();
static {
memo.put(0,0L); //fibonacci(0)
memo.put(1,1L); //fibonacci(1)
}
귀납적 단계를 위해 우리가해야 할 일은 다음과 같이 피보나치 함수를 재정의하는 것입니다.
public static long fibonacci(int x) {
return memo.computeIfAbsent(x, n -> fibonacci(n-2) + fibonacci(n-1));
}
보시 computeIfAbsent
다시피이 메서드 는 제공된 람다 식을 사용하여 숫자가지도에 없을 때 피보나치 수를 계산합니다. 이는 기존의 트리 재귀 알고리즘에 비해 상당한 개선을 나타냅니다.
다른 예시. 복잡한지도지도를 만들 때 computeIfAbsent () 메서드는지도의 get () 메서드를 대체합니다. computeIfAbsent () 호출을 함께 연결하면 누락 된 컨테이너가 제공된 람다 식에 의해 즉석에서 생성됩니다.
// Stores regional movie ratings
Map<String, Map<Integer, Set<String>>> regionalMovieRatings = new TreeMap<>();
// This will throw NullPointerException!
regionalMovieRatings.get("New York").get(5).add("Boyhood");
// This will work
regionalMovieRatings
.computeIfAbsent("New York", region -> new TreeMap<>())
.computeIfAbsent(5, rating -> new TreeSet<>())
.add("Boyhood");
This is really helpful if you want to create a Multimap without using guava library (https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html)
For eg: If you want to store a list of students who enrolled for a particular subject. The normal solution for this using jdk library is
Map<String,List<String>> studentListSubjectWise = new TreeMap<>();
List<String>lis = studentListSubjectWise.get("a");
if(lis == null) {
lis = new ArrayList<>();
}
lis.add("John");
//continue....
Since it have some boiler plate code, people tend to use guava Mutltimap.
Using Map.computeIfAbsent, we can write in a single line without guava Multimap as follows.
studentListSubjectWise.computeIfAbsent("a", (x -> new ArrayList<>())).add("John");
Stuart Marks & Brian Goetz did a good talk about this https://www.youtube.com/watch?v=9uTVXxJjuco
참고URL : https://stackoverflow.com/questions/19278443/how-do-i-use-the-new-computeifabsent-function
'development' 카테고리의 다른 글
ASP.NET MVC에서 비활성화 된 입력을 제출하려면 어떻게합니까? (0) | 2020.08.29 |
---|---|
80 이외의 포트에서 수신하도록 Apache 구성 (0) | 2020.08.29 |
React Native에서 ScrollView의 현재 스크롤 위치 가져 오기 (0) | 2020.08.29 |
XML 렌더링 오류 Android 미리보기 N (0) | 2020.08.29 |
Android API 23 플랫폼에 대한 소스를 찾을 수 없음 (Android Studio 2.0) (0) | 2020.08.29 |