名と姓のペアのマップがあり、特定の値に一致する姓を持つそのマップの最初のエントリの名を検索するとします。 Java 8の方法でこれを行うにはどうすればよいでしょう。
以下のテストケースの例では、それを行う2つの方法を示します。
ただし、最初のもの(姓が「Donkey」である最初の人の名を探す)はJava.util.NoSuchElementExceptionをスローします:値が存在しないため安全ではありません。
2つ目は動作しますが、読みにくいだけでなく、機能的ではありません。
ここで誰かがstream()
またはforEach()
のいずれか、または両方を使用してこれを達成するより簡単で明確な方法を私に提案するかどうか疑問に思います。
@Test
public void shouldBeAbleToReturnTheKeyOfTheFirstMatchingValue() throws Exception {
Map<String, String> names = new LinkedHashMap<>();
names.put("John", "Doe");
names.put("Fred", "Flintstone");
names.put("Jane", "Doe");
String keyOfTheFirst = names.entrySet().stream().filter(e -> e.getValue().equals("Doe")).findFirst().get().getKey();
assertEquals("John", keyOfTheFirst);
try {
names.entrySet().stream().filter(e -> e.getValue().equals("Donkey")).findFirst().get();
} catch (NoSuchElementException e){
// Expected
}
Optional<Map.Entry<String, String>> optionalEntry = names.entrySet().stream().filter(e -> e.getValue().equals("Donkey")).findFirst();
keyOfTheFirst = optionalEntry.isPresent() ? optionalEntry.get().getKey() : null;
assertNull(keyOfTheFirst);
}
前もって感謝します。
一致するものがない場合にデフォルト値を返すには、 Optional#orElse
names.entrySet().stream()
.filter(e -> e.getValue().equals("Donkey"))
.map(Map.Entry::getKey)
.findFirst()
.orElse(null);
同様の 質問 から:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
return map.entrySet()
.stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
その後、必要に応じて、最初のものを選択できます。 key
は一意であり、value
は一意ではないことに注意してください。
編集:コード全体(@Peter Lawreyに感謝)
package test;
import Java.util.LinkedHashMap;
import Java.util.Map;
import Java.util.Objects;
import Java.util.Optional;
public class Main {
public static void main(String[] args) {
Map<String, String> names = new LinkedHashMap<>();
names.put("John", "Doe");
names.put("Fred", "Flintstone");
names.put("Jane", "Doe");
Optional<String> firstKey = names.entrySet().stream()
.filter(entry -> Objects.equals(entry.getValue(), "Doe"))
.map(Map.Entry::getKey).findFirst();
if (firstKey.isPresent()) {
System.out.println(firstKey.get());
}
}
}
以下は、マップからキーを取得するためのコードスニペットです。
Map<String,String> pageDetails = new HashMap<String,String>();
public String getAssociatedKey(){
pageDetails.entrySet().stream().filter( e -> e.getValue().contains("John").findFirst().get().getKey();
}
Null値を持つマップエントリが存在する場合、nullポインタ例外を回避するには:
private String getValueByKey(Map<String, String> map, String key)
{
return map.entrySet().stream().filter(e ->
StringUtils.equalsIgnoreCase(e.getKey(), key)).findFirst().get()
.getValue();
}
私は昔ながらのが好きです:
static <K, V> K findFirstKeyByValue(Map<K, V> map, String value) {
for (Entry<K, V> e : map.entrySet())
if (e.getValue().equals(value))
return e.getKey();
return null;
}