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(); } }