Another common problem that we encounter in applications entails replacing the elements of a List that matches certain conditions.
In the following example, let's consider the Melon class:
public class Melon {
private final String type;
private final int weight;
// constructor, getters, equals(), hashCode(),
// toString() omitted for brevity
}
And then, let's consider a List of Melon:
List<Melon> melons = new ArrayList<>();
melons.add(new Melon("Apollo", 3000));
melons.add(new Melon("Jade Dew", 3500));
melons.add(new Melon("Cantaloupe", 1500));
melons.add(new Melon("Gac", 1600));
melons.add(new Melon("Hami", 1400));
Let's assume that we want to replace all melons weighing less than 3,000 grams with other melons of the same types and that weigh 3,000 grams.
A solution to this problem will entail iterating the List and then using List.set(int index, E element) to replace the melons accordingly.
This is a snippet of spaghetti code as follows:
for (int i = 0; i < melons.size(); i++) {
if (melons.get(i).getWeight() < 3000) {
melons.set(i, new Melon(melons.get(i).getType(), 3000));
}
}
Another solution relies on Java 8 functional style or, more precisely, on the UnaryOperator functional interface.
Based on this functional interface, we can write the following operator:
UnaryOperator<Melon> operator = t
-> (t.getWeight() < 3000) ? new Melon(t.getType(), 3000) : t;
Now, we can use the JDK 8, List.replaceAll(UnaryOperator<E> operator), as follows:
melons.replaceAll(operator);
Both approaches should perform almost the same.