Java 8 - リストをマップに変換する
2022-02-28 21:09:17
Java 8 のいくつかの例では、オブジェクトのコレクション (List) を Map に配置する方法と、複数の重複するキーを処理する方法を示しています。
ホスティング.java
package com.mkyong.java8
public class Hosting {
private int Id;
private String name;
private long websites;
public Hosting(int id, String name, long websites) {
Id = id;
this.name = name;
this.websites = websites;
}
//getters, setters and toString()
}
1. リストからマップへ - Collectors.toMap()
を作成します。
Hosting
オブジェクトのコレクションを作成し
Collectors.toMap
を使用してMapに変換します。
TestListMap.java
package com.mkyong.java8
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TestListMap {
public static void main(String[] args) {
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000));
list.add(new Hosting(2, "linode.com", 90000));
list.add(new Hosting(3, "digitalocean.com", 120000));
list.add(new Hosting(4, "aws.amazon.com", 200000));
list.add(new Hosting(5, "mkyong.com", 1));
// key = id, value - websites
Map<Integer, String> result1 = list.stream().collect(
Collectors.toMap(Hosting::getId, Hosting::getName));
System.out.println("Result 1 : " + result1);
// key = name, value - websites
Map<String, Long> result2 = list.stream().collect(
Collectors.toMap(Hosting::getName, Hosting::getWebsites));
System.out.println("Result 2 : " + result2);
// Same with result1, just different syntax
// key = id, value = name
Map<Integer, String> result3 = list.stream().collect(
Collectors.toMap(x -> x.getId(), x -> x.getName()));
System.out.println("Result 3 : " + result3);
}
}
出力
Result 1 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}
Result 2 : {liquidweb.com=80000, mkyong.com=1, digitalocean.com=120000, aws.amazon.com=200000, linode.com=90000}
Result 3 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}
<インス
2. リストをマップに - 重複キー!
2.1 以下のコードを実行すると、重複キーエラーが発生します!
TestDuplicatedKey.java
package com.mkyong.java8;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TestDuplicatedKey {
public static void main(String[] args) {
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000));
list.add(new Hosting(2, "linode.com", 90000));
list.add(new Hosting(3, "digitalocean.com", 120000));
list.add(new Hosting(4, "aws.amazon.com", 200000));
list.add(new Hosting(5, "mkyong.com", 1));
list.add(new Hosting(6, "linode.com", 100000)); // new line
// key = name, value - websites , but the key 'linode' is duplicated!
Map<String, Long> result1 = list.stream().collect(
Collectors.toMap(Hosting::getName, Hosting::getWebsites));
System.out.println("Result 1 : " + result1);
}
}
出力します。次のエラーは誤解を招くもので、キーの値の代わりに "linode" を表示する必要があります。
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 90000
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1245)
//...
2.2 上記の重複キー問題を解決するために、3つ目のパラメータを追加します。
Map<String, Long> result1 = list.stream().collect(
Collectors.toMap(Hosting::getName, Hosting::getWebsites,
(oldValue, newValue) -> oldValue
)
);
出力
Result 1 : {... , aws.amazon.com=200000, linode.com=90000}
備考
(oldValue, newValue) -> oldValue
==> キーが重複している場合、oldKeyとnewKeyのどちらを選択するのでしょうか?
3.3 newValueを試す
Map<String, Long> result1 = list.stream().collect(
Collectors.toMap(Hosting::getName, Hosting::getWebsites,
(oldValue, newValue) -> newvalue
)
);
出力
Result 1 : {... , aws.amazon.com=200000, linode.com=100000}
<イン
3. 一覧から地図へ - 並べ替え・収集
TestSortCollect.java
package com.mkyong.java8;
import java.util.*;
import java.util.stream.Collectors;
public class TestSortCollect {
public static void main(String[] args) {
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000));
list.add(new Hosting(2, "linode.com", 90000));
list.add(new Hosting(3, "digitalocean.com", 120000));
list.add(new Hosting(4, "aws.amazon.com", 200000));
list.add(new Hosting(5, "mkyong.com", 1));
list.add(new Hosting(6, "linode.com", 100000));
//example 1
Map result1 = list.stream()
.sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
.collect(
Collectors.toMap(
Hosting::getName, Hosting::getWebsites, // key = name, value = websites
(oldValue, newValue) -> oldValue, // if same key, take the old key
LinkedHashMap::new // returns a LinkedHashMap, keep order
));
System.out.println("Result 1 : " + result1);
}
}
出力
Result 1 : {aws.amazon.com=200000, digitalocean.com=120000, linode.com=100000, liquidweb.com=80000, mkyong.com=1}
P.S 上記の例では、ストリームはcollectの前にソートされているので、"linode.com=100000"は「oldValue」になります。
参考文献
関連
-
xxx は型に解決できない エラー解決
-
SLF4J: クラスパスが複数の SLF4J バインディングを含んでいる Error
-
Springの構成でエラーなくIntelliJのアイデア、アセンブリオブジェクトは、自動配線できませんでした。
-
Java 文字クラスとメソッド
-
svn: 接続から読み取ることができません。リモートホストが既存の接続を強制的に閉じました。
-
JIRA REST API 呼び出し方法
-
トークンに関する構文エラー、代わりに AnnotationName が期待される 構文エラー
-
Linux (Centos) に Java jdk をインストールしてテストするとエラーが出る - bash: java: command not found
-
メソッド起動時に InvocationException が発生しました。
-
Mavenプロジェクトレポート 言語レベル「5」ではDiamond型がサポートされない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Javaでエラーが発生しました。非静的フィールドへの静的な参照を作成できません。
-
JAVAMail TLS配信の注意点
-
mvn -v error: main class not found or couldn't be loaded org.codehaus.plexus.classworlds.launcher.
-
XXX型を囲むインスタンスはアクセスできない問題をJavaで解決
-
java にリソースリークがある: 'XXX' は決して閉じられない ソリューション
-
エラー コンストラクタ worker(int, String, float) は未定義です。
-
org.apache.tools.zip を使用した Zip 圧縮・解凍
-
Javaコースデザイン 倉庫番ゲーム
-
JAXBContextImpl を com.sun.xml.bind.v2.runtime.JAXBContextImpl にキャストできない com.sun.xml.internal.bind.api.JAXBRICoにキャストできない。
-
IDEAが新しいプロジェクトを実行すると、Error running 'XXXApplication' と表示されます。XXXAppのコマンドラインを短くしてください。