Новые методы на карте
По сравнению с Collection у Map больше методов!
forEach()
Сигнатура этого метода void forEach(BiConsumer action), и его функция заключается в выполнении операции, заданной действием, над каждой картой в Map, где BiConsumer — функциональный интерфейс, который имеет реализуемый метод недействителен (T t, U u).
Ни имя интерфейса BinConsumer, ни имя метода accept() не важны, пожалуйста, не запоминайте их.
Требование: Предположим, что существует карта чисел для соответствующих английских слов, выведите все отношения сопоставления на карте. Java7 и предыдущий классический код выглядят следующим образом:
// Java7以及之前迭代Map
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
for(Map.Entry<Integer, String> entry : map.entrySet()){
System.out.println(entry.getKey() + "=" + entry.getValue());
}
При использовании метода Map.forEach() в сочетании с анонимным внутренним классом код выглядит следующим образом:
// 使用forEach()结合匿名内部类迭代Map
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.forEach(new BiConsumer<Integer, String>(){
@Override
public void accept(Integer k, String v){
System.out.println(k + "=" + v);
}
});
Приведенный выше код вызывает метод forEach() и реализует интерфейс BiConsumer с помощью анонимного внутреннего класса.
Конечно, никто не использует анонимные внутренние классы в практических сценариях, потому что есть лямбда-выражения:
// 使用forEach()结合Lambda表达式迭代Map
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.forEach((k, v) -> System.out.println(k + "=" + v));
}
getOrDefault()
Этот метод не имеет ничего общего с лямбда-выражениями, но полезен.
Сигнатура метода — V getOrDefault(Object key, V defaultValue), которая используется для запроса соответствующего значения на карте в соответствии с заданным ключом и возврата значения по умолчанию, если оно не найдено.
Используя этот метод, программист может сохранить проблему запроса, существует ли указанное значение ключа.
Требования; предполагая, что существует карта чисел для соответствующих английских слов, выведите английское слово, соответствующее 4, и выведите NoValue, если оно не существует
// 查询Map中指定的值,不存在时使用默认值
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
// Java7以及之前做法
if(map.containsKey(4)){ // 1
System.out.println(map.get(4));
}else{
System.out.println("NoValue");
}
// Java8使用Map.getOrDefault()
System.out.println(map.getOrDefault(4, "NoValue")); // 2
putIfAbsent() Этот метод не имеет ничего общего с лямбда-выражениями, но полезен.
Сигнатура метода - V putIfAbsent(K key, V value), функция состоит в том, чтобы поместить значение, указанное значением, в карту только тогда, когда нет сопоставления значения ключа или значение сопоставления равно нулю, в противном случае карта не будет измененный.
Этот метод объединяет условное суждение и присваивание в одно, что более удобно в использовании.
remove()
Все мы знаем, что на карте есть метод удаления (ключ объекта) для удаления отношения сопоставления на карте в соответствии с указанным значением ключа; Java8 добавила метод удаления (ключ объекта, значение объекта), только в текущей карте ключ точно сопоставлен со значением, удалите сопоставление, иначе ничего не делайте.
replace()
В Java7 и более ранних версиях заменить отношение сопоставления на карте можно с помощью метода put(K key, V value), который всегда будет заменять исходное значение новым значением.
Чтобы более точно управлять поведением замены, Java8 добавляет в карту два метода replace(), а именно:
-
replace(ключ K, значение V), используйте значение для замены исходного значения только тогда, когда существует сопоставление ключа в текущей карте, в противном случае ничего не делайте.
-
replace(K key, V oldValue, V newValue), используйте newValue для замены исходного значения только тогда, когда сопоставление ключа в текущей карте существует и равно oldValue, в противном случае ничего не делайте.
replaceAll() Сигнатура этого метода — replaceAll(BiFunction super K,? super V,? extends V> function), которая выполняет операцию, указанную функцией на каждой карте на карте, и заменяет исходное значение на результат выполнения функции , где BiFunction — функциональный интерфейс, который имеет реализуемый метод R apply(T t, U u).
Не пугайтесь такого количества функциональных интерфейсов, потому что вам не нужно знать их названия, чтобы их использовать.
Требование: Предполагая, что существует сопоставление чисел с соответствующими английскими словами, преобразуйте слова в исходном сопоставлении в верхний регистр. Java7 и предыдущий классический код выглядят следующим образом:
// Java7以及之前替换所有Map中所有映射关系
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
for(Map.Entry<Integer, String> entry : map.entrySet()){
entry.setValue(entry.getValue().toUpperCase());
}
Используйте метод replaceAll() в сочетании с анонимными внутренними классами, чтобы добиться следующего:
// 使用replaceAll()结合匿名内部类实现
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.replaceAll(new BiFunction<Integer, String, String>(){
@Override
public String apply(Integer k, String v){
return v.toUpperCase();
}
});
Приведенный выше код вызывает метод replaceAll() и использует анонимный внутренний класс для реализации интерфейса BiFunction.
Идем дальше, используя лямбда-выражения для достижения следующего:
// 使用replaceAll()结合Lambda表达式实现
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.replaceAll((k, v) -> v.toUpperCase());
Невероятно лаконично.
merge()
Сигнатура этого метода — слияние (ключ K, значение V, BiFunction super V,? super V,? extends V> remappingFunction), а функция такова:
-
Если карта, соответствующая ключу в Карте, не существует или имеет значение null, свяжите значение (которое не может быть нулевым) с ключом;
-
В противном случае выполняется remappingFunction, если результат выполнения не нулевой, то результат связывается с ключом, в противном случае сопоставление ключа удаляется в Map.
Интерфейс функции BiFunction в параметрах был введен ранее, и существует метод, который необходимо реализовать R apply(T t, U u).
Хотя семантика метода merge() немного сложна, метод очень ясен.Общим сценарием является добавление новой информации об ошибке к исходной информации, например:
map.merge(key, newMsg, (v1, v2) -> v1+v2);
compute()
Сигнатура этого метода — calculate(K key, BiFunction super K,? super V,? extends V> remappingFunction), и функция должна связать результат вычисления remappingFunction с ключом. Если результат вычисления равен нулю, удалить ключ в карте сопоставления.
Чтобы реализовать приведенный выше пример объединения сообщений об ошибках в методе merge(), используйте код calculate() следующим образом:
map.compute(key, (k,v) -> v==null ? newMsg : v.concat(newMsg));
computeIfAbsent()
Сигнатура метода - V calculateIfAbsent(K key, Function super K,? extends V> mappingFunction), функция: только когда нет сопоставления значения ключа в текущей карте или значение сопоставления равно нулю, mapFunction будет вызываться, и в поле Когда результат выполнения mapFunction не равен нулю, свяжите результат с ключом.
Функция — это функциональный интерфейс с реализуемым методом R apply(T t).
calculateIfAbsent() часто используется для создания карты инициализации для определенного значения ключа Map. Например, если мы хотим реализовать карту с несколькими значениями, определение карты может быть Map
Map<Integer, Set<String>> map = new HashMap<>();
// Java7及以前的实现方式
if(map.containsKey(1)){
map.get(1).add("one");
}else{
Set<String> valueSet = new HashSet<String>();
valueSet.add("one");
map.put(1, valueSet);
}
// Java8的实现方式
map.computeIfAbsent(1, v -> new HashSet<String>()).add("yi");
Используйте calculateIfAbsent(), чтобы объединить условное суждение и операцию сложения, чтобы сделать код более кратким.
computeIfPresent()
Сигнатурой этого метода является V calculateIfPresent(K key, BiFunction super K,? super V,? extends V> remappingFunction), что является противоположностью calculateIfAbsent(), то есть только при наличии сопоставления ключа значение в текущей карте, и оно не равно null , вызовите remappingFunction, если результат remappingFunction равен нулю, удалите сопоставление ключа, в противном случае используйте результат для замены исходного сопоставления ключа.
Функция этой функции эквивалентна следующему коду:
// Java7及以前跟computeIfPresent()等效的代码
if (map.get(key) != null) {
V oldValue = map.get(key);
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null)
map.put(key, newValue);
else
map.remove(key);
return newValue;
}
return null;