vuoi
o PayPal
tutte le volte che vuoi
/*Classe da salvare in un file Lambda Utilities.java*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Questa classe dovrà contenere 4 funzioni di utilità su liste e mappe, di cui
* la prima è fornita a titolo di esempio. Tutte queste hanno come secondo
* argomento una interfaccia funzionale di libreria (package java.util.function)
* da trovare, così che potranno essere chiamate con delle lambda, come mostrato
* dal main in fondo (da "scommentare"). Realizzare i tre metodi statici qui
* sotto senza fare uso degli stream, ma possibilmente usando il più possibile
* le funzionalità delle lambda, secondo le indicazioni fornite.
*
*
*/
public final class LambdaUtilities {
private LambdaUtilities() {
}
/**
* @param list
* the input list
* @param op
* the process to run on each element
* @param <T>
* element type
* @return a new list containing, for each element of list, the element and
* a processed version
*/
public static <T> List<T> dup(final List<T> list, final UnaryOperator<T> op) {
final List<T> l = new ArrayList<>(list.size() * 2);
list.forEach(t -> {
l.add(t);
l.add(op.apply(t));
});
return l;
}
/**
* @param list
* input list
* @param pre
* predicate to execute
* @param <T>
* element type
* @return a list that intervals each element of the input list with an
* element computed passing the value to the predicate
*/
public static <T> List<Optional<T>> optFilter(final List<T> list,
final Predicate<T> pre) {
/*
* Suggerimento: valutare l'uso di Optional.filter
*/
final List<Optional<T>> l = new ArrayList<>(list.size());
list.forEach(elem -> {
l.add(Optional.ofNullable(elem).filter(pre));
// Versione senza Optional.filter
/*
* if(pre.test(elem)){ l.add(Optional.ofNullable(elem)); }else{
* l.add(Optional.empty()); }
*/
});
return l;
}
/**
* @param list
* input list
* @param op
* a function that, for each element, computes a key
* @param <T>
* element type
* @param <R>
* key type
* @return a map that groups into categories each element of the input list,
* based on the mapping done by the function
*/
public static <R, T> Map<R, Set<T>> group(final List<T> list,
final Function<T, R> op) {
/*
* Suggerimento: valutare l'uso di Map.merge
*/
final Map<R, Set<T>> map = new HashMap<>();
list.forEach((elem) -> {
final R key = op.apply(elem);
final HashSet<T> newValue = new HashSet<>();
newValue.add(elem);
map.merge(key, newValue, (set1, set2) -> {
set1.add(set2.iterator().next());
return set1;
});
});
// senza Map.merge
// final Map<R, Set<T>> map = new HashMap<>();
//
// list.forEach((elem) -> {
// R key = op.apply(elem);
//
// if (map.containsKey(key)) {
// map.get(key).add(elem);
// } else {
// Set<T> internalSet = new HashSet<>();
// map.put(key, internalSet);
// internalSet.add(elem);
// }
// });
return map;
}
/**
* @param map
* input map
* @param def
* the supplier
* @param <V>
* element type
* @param <K>
* key type
* @return a map whose non present values are filled with the value provided
* by the supplier
*/
public static <K, V> Map<K, V> fill(final Map<K, Optional<V>> map,
final Supplier<V> def) {
/*
* Suggerimento: valutare l'uso di Optional.orElse
*
* Si ricordi che si può iterare una mappa col suo metodo forEach
*/