Es gibt doch sicher einen schönen (etablierten) Begriff dafür, dass man eine Funktion, die auf einzelne Elemente angewendet werden kann, auf eine Menge von Elementen anwendet (und dann auch eine Menge als Ergebnis erhält).
(Aber vielleicht ist das auch so „trivial“, dass es gar keinen Namen gibt?)
Das ist ähnlich zu dem, was mit einem stream.map(...)
gemacht wird. Aber diesen Prozess an sich mit map
zu bezeichnen passt ja dann nicht: Es wird ja nicht gemappt, sondern das map
wird angewendet.
Im Endeffekt geht es um die Frage, was hier…
Function<S, T> function = ...;
Function<Collection<S>, Collection<T>> result = SENSIBLE_NAME(function);
anstelle von SENSIBLE_NAME
stehen könnte. Ich dachte an forEach
, lift
, map
, spread
oder ähnliches, aber alles erscheint irgendwie unpassend Im Beispiel unten heißt die Funktion forEach
, mit den zu erwartenden „Erweiterungen“, wenn man das auf höherstellige Funktionen verallgemeinern will.
Websuchen liefern immer entweder random crap, oder eben genau das, was mit dem Namen gemeint ist, den man mit in die Websuche aufnimmt, und was dann meistens nicht das ist, was man sucht, sondern das, was dieser Name eben bedeutet …
Hat jemand einen passenden Namen dafür?
package de.javagl.fungen.temp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
public class FunGenExample
{
public static void main(String[] args)
{
forEach();
forEach0();
forEach1();
forEachCartesian();
}
private static void forEach()
{
List<String> strings = Arrays.asList("0", "1", "2", "3");
Function<String, Integer> function = Integer::parseInt;
Function<Collection<String>, Collection<Integer>> result = forEach(function);
Collection<Integer> results = result.apply(strings);
System.out.println("forEach " + results);
}
private static void forEach0()
{
List<Integer> integers = Arrays.asList(0, 1, 2, 3);
BiFunction<Integer, Integer, Integer> function = (i, j) -> i + j;
BiFunction<Collection<Integer>, Integer, Collection<Integer>> result = forEach0(function);
Collection<Integer> results = result.apply(integers, 123);
System.out.println("forEach0 " + results);
}
private static void forEach1()
{
List<Integer> integers = Arrays.asList(0, 1, 2, 3);
BiFunction<Integer, Integer, Integer> function = (i, j) -> i + j;
BiFunction<Integer, Collection<Integer>, Collection<Integer>> result = forEach1(function);
Collection<Integer> results = result.apply(123, integers);
System.out.println("forEach1 " + results);
}
private static void forEachCartesian()
{
List<Integer> integers = Arrays.asList(0, 1, 2, 3);
BiFunction<Integer, Integer, Integer> function = (i, j) -> i + j;
BiFunction<Collection<Integer>, Collection<Integer>, Collection<Integer>> result = forEachCartesian(function);
Collection<Integer> results = result.apply(integers, integers);
System.out.println("forEachCartesian " + results);
}
private static <S, T> Function<Collection<S>, Collection<T>> forEach(
Function<S, T> function)
{
return ss ->
{
List<T> ts = new ArrayList<T>();
for (S s : ss)
{
ts.add(function.apply(s));
}
return ts;
};
}
private static <T, U, R> BiFunction<Collection<T>, U, Collection<R>> forEach0(
BiFunction<T, U, R> function)
{
return (ts, u) -> forEach(curry1(function, u)).apply(ts);
}
private static <T, U, R> BiFunction<T, Collection<U>, Collection<R>> forEach1(
BiFunction<T, U, R> function)
{
return (t, us) -> forEach(curry0(function, t)).apply(us);
}
private static <A, B, R> Function<B, R> curry0(
BiFunction<? super A, ? super B, ? extends R> f, A a)
{
return b -> f.apply(a, b);
}
private static <A, B, R> Function<A, R> curry1(
BiFunction<? super A, ? super B, ? extends R> f, B b)
{
return a -> f.apply(a, b);
}
private static <T, U, R> BiFunction<Collection<T>, Collection<U>, Collection<R>> forEachCartesian(
BiFunction<T, U, R> function)
{
return (ts, us) ->
{
List<R> rs = new ArrayList<R>();
for (T t : ts)
{
for (U u : us)
{
rs.add(function.apply(t, u));
}
}
return rs;
};
}
}