Java 8ストリームAPIを使って `Map`をフィルタリングする方法を示すJavaの例はほとんどありません。
Java 8より前:
Map<Integer, String> map = new HashMap<>(); map.put(1, "linode.com"); map.put(2, "heroku.com"); String result = ""; for (Map.Entry<Integer, String> entry : map.entrySet()) { if("something".equals(entry.getValue())){ result = entry.getValue(); } }
Java 8では、
Map.entrySet()`を `stream`に変換し、それに
filter()
と
collect() `を続けることができます。
Map<Integer, String> map = new HashMap<>(); map.put(1, "linode.com"); map.put(2, "heroku.com"); //Map -> Stream -> Filter -> String String result = map.entrySet().stream() .filter(x -> "something".equals(x.getValue())) .map(x->x.getValue()) .collect(Collectors.joining()); //Map -> Stream -> Filter -> MAP Map<Integer, String> collect = map.entrySet().stream() .filter(x -> x.getKey() == 2) .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue())); //or like this Map<Integer, String> collect = map.entrySet().stream() .filter(x -> x.getKey() == 3) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
1. Java 8 – マップのフィルタリング
値でマップをフィルタリングして文字列を返す完全な例。
TestMapFilter.java
package com.mkyong; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class TestMapFilter { public static void main(String[]args) { Map<Integer, String> HOSTING = new HashMap<>(); HOSTING.put(1, "linode.com"); HOSTING.put(2, "heroku.com"); HOSTING.put(3, "digitalocean.com"); HOSTING.put(4, "aws.amazon.com"); //Before Java 8 String result = ""; for (Map.Entry<Integer, String> entry : HOSTING.entrySet()) { if ("aws.amazon.com".equals(entry.getValue())) { result = entry.getValue(); } } System.out.println("Before Java 8 : " + result); //Map -> Stream -> Filter -> String result = HOSTING.entrySet().stream() .filter(map -> "aws.amazon.com".equals(map.getValue())) .map(map -> map.getValue()) .collect(Collectors.joining()); System.out.println("With Java 8 : " + result); //filter more values result = HOSTING.entrySet().stream() .filter(x -> { if (!x.getValue().contains("amazon") && !x.getValue().contains("digital")) { return true; } return false; }) .map(map -> map.getValue()) .collect(Collectors.joining(",")); System.out.println("With Java 8 : " + result); } }
出力
Before Java 8 : aws.amazon.com With Java 8 : aws.amazon.com With Java 8 : linode.com,heroku.com
2. Java 8 – マップ#2のフィルタリング
さらに別の例では、
Map`をキーでフィルタリングしますが、今回は
Map`を返します。
TestMapFilter2.java
package com.mkyong; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class TestMapFilter2 { public static void main(String[]args) { Map<Integer, String> HOSTING = new HashMap<>(); HOSTING.put(1, "linode.com"); HOSTING.put(2, "heroku.com"); HOSTING.put(3, "digitalocean.com"); HOSTING.put(4, "aws.amazon.com"); //Map -> Stream -> Filter -> Map Map<Integer, String> collect = HOSTING.entrySet().stream() .filter(map -> map.getKey() == 2) .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue())); System.out.println(collect);//output : {2=heroku.com} Map<Integer, String> collect2 = HOSTING.entrySet().stream() .filter(map -> map.getKey() <= 3) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); System.out.println(collect2);//output : {1=linode.com, 2=heroku.com, 3=digitalocean.com} } }
出力
{2=heroku.com} {1=linode.com, 2=heroku.com, 3=digitalocean.com}
3. Java 8 – マップのフィルタリング#3 – 述語
今回は、新しいJava 8の「述語」を試してみてください。
TestMapFilter3.java
package com.mkyong; import java.util.HashMap; import java.util.Map; import java.util.function.Predicate; import java.util.stream.Collectors; public class TestMapFilter3 { //Generic Map filterbyvalue, with predicate public static <K, V> Map<K, V> filterByValue(Map<K, V> map, Predicate<V> predicate) { return map.entrySet() .stream() .filter(x -> predicate.test(x.getValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } public static void main(String[]args) { Map<Integer, String> HOSTING = new HashMap<>(); HOSTING.put(1, "linode.com"); HOSTING.put(2, "heroku.com"); HOSTING.put(3, "digitalocean.com"); HOSTING.put(4, "aws.amazon.com"); HOSTING.put(5, "aws2.amazon.com"); // {1=linode.com} Map<Integer, String> filteredMap = filterByValue(HOSTING, x -> x.contains("linode")); System.out.println(filteredMap); //{1=linode.com, 4=aws.amazon.com, 5=aws2.amazon.com} Map<Integer, String> filteredMap2 = filterByValue(HOSTING, x -> (x.contains("aws") || x.contains("linode"))); System.out.println(filteredMap2); //{4=aws.amazon.com} Map<Integer, String> filteredMap3 = filterByValue(HOSTING, x -> (x.contains("aws") && !x.contains("aws2"))); System.out.println(filteredMap3); //{1=linode.com, 2=heroku.com} Map<Integer, String> filteredMap4 = filterByValue(HOSTING, x -> (x.length() <= 10)); System.out.println(filteredMap4); } }
出力
{1=linode.com} {1=linode.com, 4=aws.amazon.com, 5=aws2.amazon.com} {4=aws.amazon.com} {1=linode.com, 2=heroku.com}
参考文献
Java SE 8ストリームによるデータ]。
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
[Java
コレクターズJavaDoc]。リンク://java8/java-8-streams-filter-examples/[Java 8 Streamsフィルタ
例]