package base; import java.util.*; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; /** * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) */ public final class Functional { private Functional() {} public static List map( final Collection items, final Function f ) { return items.stream().map(f).collect(Collectors.toUnmodifiableList()); } public static List map( final List items, final BiFunction f ) { return IntStream.range(0, items.size()) .mapToObj(i -> f.apply(i, items.get(i))) .collect(Collectors.toUnmodifiableList()); } public static Map mapValues( final Map map, final Function f ) { return map .entrySet() .stream() .collect( Collectors.toMap(Map.Entry::getKey, e -> f.apply(e.getValue())) ); } @SafeVarargs public static Map mergeMaps(final Map... maps) { return Stream.of(maps) .flatMap(m -> m.entrySet().stream()) .collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a ) ); } @SafeVarargs public static List concat(final Collection... items) { final List result = new ArrayList<>(); for (final Collection item : items) { result.addAll(item); } return result; } public static List append( final Collection collection, final T item ) { final List list = new ArrayList<>(collection); list.add(item); return list; } public static List> allValues( final List vals, final int length ) { return Stream.generate(() -> vals) .limit(length) .reduce( List.of(List.of()), (prev, next) -> next .stream() .flatMap(value -> prev.stream().map(list -> append(list, value)) ) .toList(), (prev, next) -> next .stream() .flatMap(suffix -> prev.stream().map(prefix -> concat(prefix, suffix)) ) .toList() ); } public static V get(final Map map, final K key) { final V result = map.get(key); if (result == null) { throw new NullPointerException( key.toString() + " in " + map(map.keySet(), Objects::toString) ); } return result; } public static void addRange( final List values, final int d, final int c ) { for (int i = -d; i <= d; i++) { values.add(c + i); } } public static void forEachPair( final T[] items, final BiConsumer consumer ) { assert items.length % 2 == 0; IntStream.range(0, items.length / 2).forEach(i -> consumer.accept(items[i * 2], items[i * 2 + 1]) ); } public static List> toPairs(final T[] items) { assert items.length % 2 == 0; return IntStream.range(0, items.length / 2) .mapToObj(i -> Pair.of(items[i * 2], items[i * 2 + 1])) .toList(); } }