Java 8 – New methods in Collections

Introduction

In the first article we learned about Lambdas, functional interfaces and method references introduced in Java 8. In the previous article we saw default methods in interfaces and their inheritance rules. In this article we look at the new default methods added in the Collections hierarchy. Many of the new methods make use of lambda expressions to simplify operations on Collections.These methods make iterating through the collections easier. The developer is freed from actually performing the iteration, and can concentrate only on what happens in each iteration. The advantage is a) easier to read code and b) faster to develop. Here are the methods

void forEach(Consumer<? super T> action) Iterable

Iterates over each element of the List and calls the lambda expression specified by ‘action’.

List<Double> temperature = 
   new ArrayList<Double<(Arrays.asList(new Double[] { 20.0, 22.0, 22.5 }));
temperature.forEach(s -> System.out.println(s));
 // prints the number in separate lines
// or written using method references
temperature.forEach(System.out::println);

boolean removeIf(Predicate<? super E> filter) Collection

Iterates through the Collection and removes the element that matches the filter.

temperature.removeIf(s -> s > 22);
// remove elements that are > 22

boolean removeIf(Predicate<? super E> filter)Collection

This is a very useful method. It replaces all elements in the List with the result of applying the operator (apply method)

temperature.replaceAll(s->Math.pow(s, 0.5));
// replaces all elements by its square root

void sort(Comparator<? super E> c)List

Sorts the element using the provided comparator. This example sorts the elements in descending order

temperature.sort((a, b) -> a > b ? -1 : 1);

void forEach(BiConsumer<? super K, ? super V> action)Map

This method performs the operation specified in the ‘action’ on each Map Entry (key and value pair). It iterates in the order of the key set.

authorBooks.forEach((a, b) -> System.out.println(a + " wrote " + b + " books"));
Map<String , Integer> authorBooks = new HashMap<String , Integer>();
authorBooks.put("Robert Ludlum", 27);
authorBooks.put("Clive Cussler", 50);
authorBooks.put("Tom Clancy", 17);

							

V compute(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction)List

This method replaces the value of a key by the value computer from the remappingFunction. In this example we replace the number of books written by Clive Cussler to original count(50) +1

authorBooks.compute(“Clive Cussler”, (a, b) -> b + 1);

If the compute function returns null then the entry for that key is removed from the map. If the key is not present then a new entry is added.

V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)Map

This method adds an entry in the Map. the key is specified in the function and the value is the result of the application of the mapping function. In our slightly weird example, we add the number of books written by ‘Agatha Christie’ as the number of alphabets in the authors name

authorBooks.computeIfAbsent("Agatha Christie", b -> b.length());

The entry is added only if the computed value is not null.

V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunctionMap

This function is simlar to the compute function, however the difference is that the compute function adds or modifies an existing entry whereas this function does nothing if an entry with that key is not present. Note that this function also removes an element if the new value computed from the passed lambda expression is null.

 authorBooks.computeIfPresent("Tom Clancy", (a, b) -> b + 1);

V getOrDefault(Object key, V defaultValue)Map

Returns the value mapped to the key, or if the key is not present, returns the default value.

authorBooks.getOrDefault("AuthorA", 0)

the map does not contain ‘AuthorA’ so this returns 0.

V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunctionMap

If the key is not present or if the value for the key is null, then adds the key-value pair to the map. If the key is present then replaces the value with the value from the remapping function. If the remapping function return null then the key is removed from the map.

authorBooks.merge("AuthorB", 1, (a, b) -> a + b);
System.out.println(authorBooks.get("AuthorB"));// 1
authorBooks.merge("AuthorB", 1, (a, b) -> a + b);
System.out.println(authorBooks.get("AuthorB"));//2

V putIfAbsent(K key, V value)Map

if the key is not present or if the key is mapped to null, then the key-value pair is added to the map and the result returns null. If the key is already mapped to a value, then that value is returned

System.out.println(authorBooks.putIfAbsent("AuthorC", 2));//null
System.out.println(authorBooks.putIfAbsent("AuthorC", 2));//2

boolean remove(Object key, Object value) Map

removes the key only if its associated with the given value

V replace(K key, V newValue) Map

If the key is present then the value is replaced by newValue. If the key is not present, does nothing.

boolean replace(K key, V oldValue, V newValue) Map

If the key is present and is mapped to the oldValue, then it is remapped to the newValue.

void replaceAll (BiFunction<? super K, ? super V, ? extends V> function) Map

replaces all values by the values computed from this function.

authorBooks.replaceAll((a,b)->a.length()+b);

replaces the count of books by the letters in authors words + original count

1 thought on “Java 8 – New methods in Collections”

Leave a Comment