検索
ホームページJava&#&チュートリアルMap.merge() の詳細な紹介 (コード付き)

Map.merge() の詳細な紹介 (コード付き)

Mar 22, 2019 pm 05:04 PM
javamapmerge

この記事では、Map.merge() の詳細な紹介 (コード付き) を紹介します。これには一定の参考値があります。必要な友人は参照できます。お役に立てば幸いです。

今日は Map のマージ メソッドを紹介し、その威力を見てみましょう。

JDK API では、このようなメソッドは非常に特殊で、非常に斬新なので、時間をかけて理解する価値があります。また、実際のプロジェクト コードに適用することをお勧めします。とても助かりました。 Map.merge())。これはおそらく Map 上で最も多用途な操作です。しかし、これはあまり知られていないため、使用している人はほとんどいません。

背景紹介

merge() は次のように説明できます。キーに新しい値を割り当てるか (キーが存在しない場合)、既存のキーを指定された値で更新します (UPSERT)。 。最も基本的な例、つまり一意の単語の出現数をカウントすることから始めましょう。 Java 8 より前は、コードは非常に複雑で、実際の実装では本質的な設計上の意味が失われていました。

var map = new HashMap<string>();
words.forEach(word -> {
    var prev = map.get(word);
    if (prev == null) {
        map.put(word, 1);
    } else {
        map.put(word, prev + 1);
    }
});</string>

上記のコードのロジックによれば、入力セットが与えられたと仮定すると、出力結果は次のようになります;

var words = List.of("Foo", "Bar", "Foo", "Buzz", "Foo", "Buzz", "Fizz", "Fizz");
//...
{Bar=1, Fizz=2, Foo=3, Buzz=2}

V1

次に、それを再構築してみましょう。 、主に判定ロジックの一部を削除;

words.forEach(word -> {
    map.putIfAbsent(word, 0);
    map.put(word, map.get(word) + 1);
});

このような改善により、再構築の要件を満たすことができます。 putIfAbsent() の具体的な使用法については詳しく説明しません。コード行 putIfAbsent は必ず必要です。そうでないと、後続のロジックでエラーが報告されます。以下のコードでは、put と get が再度出現するのが奇妙ですが、引き続き設計を改善していきます。

V2

words.forEach(word -> {
    map.putIfAbsent(word, 0);
    map.computeIfPresent(word, (w, prev) -> prev + 1);
});

computeIfPresent を改善すると、単語にキーが存在する場合にのみ指定された変換が呼び出されます。それ以外の場合は何も処理しません。キーをゼロに初期化することでキーが存在することを確認するため、増分は常に有効になります。この実装は十分に完璧ですか?必ずしも必要というわけではありませんが、追加の初期化を減らすための他のアイデアもあります。

words.forEach(word ->
        map.compute(word, (w, prev) -> prev != null ? prev + 1 : 1)
);

compute () は computeIfPresent() に似ていますが、指定されたキーの有無に関係なく呼び出されます。 key の値が存在しない場合、prev パラメータは null になります。単純な if をラムダに隠された三項式に移動することも、最適なパフォーマンスからは程遠いです。最終バージョンを紹介する前に、Map.merge() のデフォルト実装の少し簡略化したソース コード分析を見てみましょう。

V3 の改善

merge() ソース コード
default V merge(K key, V value, BiFunction<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;
}</v>

コード スニペットは千の言葉に匹敵します。ソース コードを読むことで、いつでも新しい発見ができるので、merge() は両方の状況に適しています。指定されたキーが存在しない場合は、put(key, value) になります。ただし、キーにすでに値が含まれている場合、remappingFunction はマージを選択できます。この機能は上記のシナリオに最適です:

  • 新しい値を返して古い値を上書きするだけです: (old, new) -> new
  • 古い値を保持するには、古い値を返すだけです: (old, new) -> old
  • 次のような方法で 2 つをマージします: (old, new) - > old new
  • 古い値も削除します: (old, new) -> null

ご覧のとおり、マージされています。 () は非常に一般的です。そこで、私たちの質問は、merge() をどのように使用するかということです。コードは次のとおりです:

words.forEach(word ->
        map.merge(word, 1, (prev, one) -> prev + one)
);

次のように理解できます: キーがない場合、初期化された値は 1 に等しく、そうでない場合は既存の値に 1 が追加されます。このシナリオではデフォルトは常にプラス 1 であり、特定の変更は自由に切り替えることができるため、コード内の 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>();
operations.forEach(op -> {
    var key = op.getAccNo();
    balances.putIfAbsent(key, BigDecimal.ZERO);
    balances.computeIfPresent(key, (accNo, prev) -> prev.add(op.getAmount()));
});</string>

マージ後のコードを使用します

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 には、指定された amountaccNo が与えられます。

{ 123 = 9.5,456 = - 100 }

ConcurrentHashMap

ConcurrentHashMap まで拡張すると、Map.merge が登場すると、ConcurrentHashMap との組み合わせは非常に完璧です。この一致シナリオは、挿入または更新操作を自動的に実行するシングルスレッドセーフなロジック用です。

この記事はここで終了しています。その他のエキサイティングなコンテンツについては、PHP 中国語 Web サイトの Java チュートリアル ビデオ 列に注目してください。

以上がMap.merge() の詳細な紹介 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はsegmentfaultで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
JVMはオペレーティングシステムAPIの違いをどのように処理しますか?JVMはオペレーティングシステムAPIの違いをどのように処理しますか?Apr 27, 2025 am 12:18 AM

JVMは、JavanativeInterface(JNI)およびJava Standard Libraryを介してオペレーティングシステムのAPIの違いを処理します。1。JNIでは、Javaコードがローカルコードを呼び出し、オペレーティングシステムAPIと直接対話できます。 2. Java Standard Libraryは統一されたAPIを提供します。これは、異なるオペレーティングシステムAPIに内部的にマッピングされ、コードがプラットフォーム間で実行されるようにします。

Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Apr 27, 2025 am 12:15 AM

modularitydoesnotdirectlyectlyectjava'splatformindepensence.java'splatformendepenceismaindainededainededainededaindainedaindained bythejvm、butmodularityinfluencesApplucationStructure andmanagement、間接的なインパクチャプラット形成依存性.1)

ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?Apr 27, 2025 am 12:06 AM

bytecodeinjavaisthe intermediaterepresentationthateNablesplatformindepence.1)javacodeis compiledintobytecodestoredin.classfiles.2)thejvminterpretsorcompilesthisbytecodeintomachinecodeatime、

Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Apr 27, 2025 am 12:03 AM

javaachievesplatformedenceTheTheTheJavavirtualMachine(JVM)、これは、javacodeisisisisisissompiledIntobytecode.2)javaCodeisisisisissompiledevedevicetecode.2)

グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?Apr 27, 2025 am 12:02 AM

Javagui開発におけるプラットフォームの独立性は課題に直面していますが、Swing、Javafx、統一外観、パフォーマンス最適化、サードパーティライブラリ、クロスプラットフォームテストを使用することで対処できます。 Javaguiの開発は、クロスプラットフォームの一貫性を提供することを目的としたAWTとSwingに依存していますが、実際の効果はオペレーティングシステムごとに異なります。ソリューションには以下が含まれます。1)SwingおよびJavafxをGUIツールキットとして使用します。 2)uimanager.setlookandfeel()を介して外観を統合します。 3)さまざまなプラットフォームに合わせてパフォーマンスを最適化します。 4)ApachepivotやSWTなどのサードパーティライブラリを使用する。 5)一貫性を確保するために、クロスプラットフォームテストを実施します。

Java開発のどの側面がプラットフォームに依存していますか?Java開発のどの側面がプラットフォームに依存していますか?Apr 26, 2025 am 12:19 AM

javadevelopmentisnotentirelylylypratform-IndopentDuetoseveralfactors.1)jvmvariationsaffectperformanceandbehavioracrossdifferentos.2)nativeLibrariesviajniintroducePlatform-specificissues.3)giaiasystemsdifferbeTioneplateplatifflics.4)

さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?Apr 26, 2025 am 12:15 AM

Javaコードは、さまざまなプラットフォームで実行するときにパフォーマンスの違いがあります。 1)JVMの実装と最適化戦略は、OracleJDKやOpenJDKなどとは異なります。 2)メモリ管理やスレッドスケジューリングなどのオペレーティングシステムの特性もパフォーマンスに影響します。 3)適切なJVMを選択し、JVMパラメーターとコード最適化を調整することにより、パフォーマンスを改善できます。

Javaのプラットフォームの独立性の制限は何ですか?Javaのプラットフォームの独立性の制限は何ですか?Apr 26, 2025 am 12:10 AM

java'splatformindepentedencehaslimitationsincludingporformanceoverhead、versioncompatibulisisues、changleSwithnativeLibraryIntegration、プラットフォーム固有の機能、およびjvminStallation/maintenation。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。