이 글은 Map.merge()(코드 포함)에 대한 자세한 소개를 담고 있습니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
오늘은 Map의 병합 방법을 소개합니다.
JDK API에서 이러한 메소드는 매우 특별하고, 매우 참신하고, 시간을 들여 이해할 가치가 있으며, 실제 프로젝트 코드에 적용할 수도 있다는 것이 좋습니다. 당신에게 큰 도움이 됩니다. Map.merge()). 이것은 아마도 Map에서 가장 다재다능한 작업일 것입니다. 그러나 그것은 또한 매우 모호하고 그것을 사용하는 사람이 거의 없습니다.
배경 소개
merge()는 다음과 같이 설명할 수 있습니다. 키에 새 값을 할당하거나(존재하지 않는 경우) 기존 키를 주어진 값으로 업데이트합니다. 값(UPSERT). 가장 기본적인 예부터 시작해 보겠습니다. 고유한 단어 발생 횟수를 세는 것입니다. Java 8 이전에는 코드가 매우 혼란스러웠고, 실제 구현에서는 본질적인 디자인 의미를 잃어버렸습니다.
var map = new HashMap<String, Integer>(); words.forEach(word -> { var prev = map.get(word); if (prev == null) { map.put(word, 1); } else { map.put(word, prev + 1); } });
위 코드의 논리에 따라 입력 세트가 있다고 가정하면 출력 결과는 다음과 같습니다.
var words = List.of("Foo", "Bar", "Foo", "Buzz", "Foo", "Buzz", "Fizz", "Fizz"); //... {Bar=1, Fizz=2, Foo=3, Buzz=2}
Improve V1
#🎜🎜 #이제 리팩토링을 수행하면 주로 판단 논리 중 일부가 제거됩니다.words.forEach(word -> { map.putIfAbsent(word, 0); map.put(word, map.get(word) + 1); });
words.forEach(word -> { map.putIfAbsent(word, 0); map.computeIfPresent(word, (w, prev) -> prev + 1); });
words.forEach(word -> map.compute(word, (w, prev) -> prev != null ? prev + 1 : 1) );
코드 조각은 천 단어의 가치가 있습니다. merge()는 두 가지 상황 모두에 적합하므로 언제든지 새로운 땅을 발견할 수 있습니다. 주어진 키가 존재하지 않으면 put(key, value)가 됩니다. 그러나 키에 이미 일부 값이 있으면 remappingFunction이 병합을 선택할 수 있습니다. 이 기능은 위의 시나리오에 적합합니다.default V merge(K key, V value, BiFunction<V, V, V> remappingFunction) { V oldValue = get(key); V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value); if (newValue == null) { remove(key); } else { put(key, newValue); } return newValue; }로그인 후 복사
(old, new) -> li><li>단순히 반환하여 이전 값을 유지합니다. <code> (old, new) -> old
(old, new) -> new
(old, new) -> old
(old, new) -> old + new
(old, new) -> null
如你所见,它 merge() 是非常通用的。那么,我们的问题该如何使用merge()呢?代码如下:
words.forEach(word -> map.merge(word, 1, (prev, one) -> prev + one) );
你可以按照如下思路理解:如果没有key,那么初始化的value等于1;否则,将1添加到现有值。代码中的 one 是一个常量,因为我们的场景中,默认一直是加1,具体变化可以随意切换。
场景
想象一下,merge()真的那么好用吗?它的场景可以有什么?
举一个例子。你有一个帐户操作类
class Operation { private final String accNo; private final BigDecimal amount; }
以及针对不同帐户的一系列操作:
operations = List.of( new Operation("123", new BigDecimal("10")), new Operation("456", new BigDecimal("1200")), new Operation("123", new BigDecimal("-4")), new Operation("123", new BigDecimal("8")), new Operation("456", new BigDecimal("800")), new Operation("456", new BigDecimal("-1500")), new Operation("123", new BigDecimal("2")), new Operation("123", new BigDecimal("-6.5")), new Operation("456", new BigDecimal("-600")) );
我们希望为每个帐户计算余额(总运营金额)。假如不用merge(),就变得非常麻烦了:
Map balances = new HashMap<String, BigDecimal>(); operations.forEach(op -> { var key = op.getAccNo(); balances.putIfAbsent(key, BigDecimal.ZERO); balances.computeIfPresent(key, (accNo, prev) -> prev.add(op.getAmount())); });
使用merge之后的代码
operations.forEach(op -> balances.merge(op.getAccNo(), op.getAmount(), (soFar, amount) -> soFar.add(amount)) );
再进行优化的逻辑。
operations.forEach(op -> balances.merge(op.getAccNo(), op.getAmount(), BigDecimal::add) );
当然结果是正确的,这样简洁的代码心动吗?对于每个操作,add
在给定的amount
给定accNo
어떤 방식으로든 두 값을 병합합니다. > (기존, 신규) -> 기존 + 신규
(기존, 신규) -> null <p style="white-space: normal;">보시다시피 merge()는 매우 다재다능합니다. 그래서 우리의 질문은 merge()를 어떻게 사용하는가 하는 것입니다. 코드는 다음과 같습니다. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">{ 123 = 9.5,456 = - 100 }</pre><div class="contentsignin">로그인 후 복사</div></div>
<p>다음과 같이 이해할 수 있습니다. 키가 없으면 초기화된 값은 1과 같고, 그렇지 않으면 기존 값에 1이 추가됩니다. 코드에서 하나는 상수입니다. 왜냐하면 우리 시나리오에서는 기본값이 항상 더하기 1이고 특정 변경 사항을 마음대로 전환할 수 있기 때문입니다. </p>
<p>scenario<a href="http://www.php.cn/course/list/36.html" target="_blank"></a>Imagine, merge()가 정말 사용하기 쉽나요? 그 장면은 무엇입니까? </p>#🎜🎜#예를 들어보세요. 계정 작업 클래스 #🎜🎜#rrreee#🎜🎜#와 다양한 계정에 대한 일련의 작업이 있습니다. #🎜🎜#rrreee#🎜🎜# 각 계정의 잔액(총 운영 금액)을 계산하려고 합니다. merge()를 사용하지 않으면 매우 번거로워집니다: #🎜🎜#rrreee#🎜🎜#병합 후 코드 사용#🎜🎜#rrreee#🎜🎜#최적화의 논리. #🎜🎜#rrreee#🎜🎜#물론 결과는 정확합니다. 이렇게 간결한 코드가 마음에 드시나요? 각 작업에 대해 <code>add
는 accNo
에 지정된 금액
을 제공합니다. #🎜🎜#rrreee#🎜🎜#ConcurrentHashMap#🎜🎜##🎜🎜#ConcurrentHashMap으로 확장하면 Map.merge가 나타나면 ConcurrentHashMap과의 조합이 매우 완벽합니다. 이 일치 시나리오는 삽입 또는 업데이트 작업을 자동으로 수행하는 단일 스레드로부터 안전한 논리를 위한 것입니다. #🎜🎜##🎜🎜#이 기사는 여기서 끝났습니다. 더 흥미로운 콘텐츠를 보려면 PHP 중국어 웹사이트의 #🎜🎜#JavaTutorial Video#🎜🎜# 칼럼을 주목하세요! #🎜🎜#위 내용은 Map.merge()에 대한 자세한 소개(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!