Background
With introduction of functional interfaces and Lambda expressions there are some new APIs introduced in collection class. In this post we will look at those.
Conditional removal [Collection.removeIf]
There is a new method added in Collection interface as -
- boolean removeIf(Predicate<? super E> filter)
This basically removes elements from the list that match the predicate. No magic here if you see the default implementation it is as follows -
1 2 3 4 5 6 7 8 9 10 11 12 | default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false ; final Iterator<E> each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true ; } } return removed; } |
So you basically iterate on your collection using a iterator and remove all elements that match your predicate condition.
Let's see an example now -
1 2 3 4 5 6 7 8 9 10 | List<String> countriesList = new ArrayList<>(); countriesList.add( "India" ); countriesList.add( "Srilanka" ); countriesList.add( "Nepal" ); countriesList.add( "Italy" ); countriesList.add( "Bhutan" ); countriesList.add( "Ireland" ); System.out.println( "Before : " + countriesList); countriesList.removeIf(s -> s.startsWith( "I" )); System.out.println( "After : " + countriesList); |
Output is :
Before : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
After : [Srilanka, Nepal, Bhutan]
After : [Srilanka, Nepal, Bhutan]
As you can see all Strings in the list starting with 'I' are removed as defined by the predicate.
and the output is :
Before : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
After : [Miss India, Miss Srilanka, Miss Nepal, Miss Italy, Miss Bhutan, Miss Ireland]
NOTE : Recollect UnaryOperator takes a single argument of type t and returns a value of same type t. If you wish to recollect common functional interfaces check out the links in the Related links section below.
and the output is -
Before : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
India
Srilanka
Nepal
Italy
Bhutan
Ireland
After : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
NOTE : Careful. Do not alter the List with the action or you will get - java.util.ConcurrentModificationException
NOTE : Above method reference System.out::println is same as saying s -> System.out.println(s)
It's method is as follows -
Updating all elements(List.replaceAll)
Another method that is introduced is -
- void replaceAll(UnaryOperator<E> o)
1 2 3 4 5 6 7 8 9 10 | List<String> countriesList = new ArrayList<>(); countriesList.add( "India" ); countriesList.add( "Srilanka" ); countriesList.add( "Nepal" ); countriesList.add( "Italy" ); countriesList.add( "Bhutan" ); countriesList.add( "Ireland" ); System.out.println( "Before : " + countriesList); countriesList.replaceAll(s -> "Miss " + s); System.out.println( "After : " + countriesList); |
and the output is :
Before : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
After : [Miss India, Miss Srilanka, Miss Nepal, Miss Italy, Miss Bhutan, Miss Ireland]
NOTE : Recollect UnaryOperator takes a single argument of type t and returns a value of same type t. If you wish to recollect common functional interfaces check out the links in the Related links section below.
Iterating over a List (List.forEach)
Another useful method that is added in List is -
- public void forEach(Consumer<? super E> action)
1 2 3 4 5 6 7 8 9 10 | List<String> countriesList = new ArrayList<>(); countriesList.add( "India" ); countriesList.add( "Srilanka" ); countriesList.add( "Nepal" ); countriesList.add( "Italy" ); countriesList.add( "Bhutan" ); countriesList.add( "Ireland" ); System.out.println( "Before : " + countriesList); countriesList.forEach(System.out::println); System.out.println( "After : " + countriesList); |
and the output is -
Before : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
India
Srilanka
Nepal
Italy
Bhutan
Ireland
After : [India, Srilanka, Nepal, Italy, Bhutan, Ireland]
NOTE : Careful. Do not alter the List with the action or you will get - java.util.ConcurrentModificationException
NOTE : Above method reference System.out::println is same as saying s -> System.out.println(s)
New APIs added in Map
New APIs added -
- merge()
- putIfAbsent() : puts in map is key is not present or the value is null
- computeIfPresent() : calls the BiFunction when the requested key is found
- computeIfAbsent() : calls the BiFunction when the key isn’t present or
is null
It's method is as follows -
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); V oldValue = get(key); V newValue = (oldValue == null ) ? value : remappingFunction.apply(oldValue, value); if (newValue == null ) { remove(key); } else { put(key, newValue); } return newValue; } |
Above is the default implementation in Map method. Quick observation :
- If old value is null, bifunction is never called.
- If mapping function returns null key is removed from the Map.
- default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
- default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)