@Seth——这是你的泛型示例。由于泛型在运行时不存在,我不明白您为什么担心失去“灵活性”。如果您使用泛型,那么您只是在使用对象。
如果您希望 F 的行为根据 G 的返回类型而有所不同,那么您只需声明您的 F 执行类似 F 的操作,简单易行。
//=== Function.java
public interface Function<ReturnType, Type> {
ReturnType doWork(Type arg);
}
//=== SomethingWeird.java
import java.util.*;
// yo dawg, i heard you liked functions. so i put a function in yo'
// function, so you can derive while you derive.
public class SomethingWeird {
public static <FReturnType, FType, GType> List<FReturnType> collateOrSomething(
Iterable<GType> objects,
Iterable<Function<FReturnType, FType>> fList,
Iterable<Function<FType, GType>> gList
) {
List<FReturnType> results = new ArrayList<FReturnType>();
for (GType garg : objects) {
for (Function<FReturnType, FType> f : fList) {
for (Function<FType, GType> g : gList) {
results.add(f.doWork(g.doWork(garg)));
}
}
}
return results;
}
}
//=== SomethingWeirdTest.java
import java.util.*;
import org.junit.*;
import static org.junit.Assert.*;
public class SomethingWeirdTest {
// this is kinda silly, and...
public static class F1 implements Function<Integer, Double> {
@Override
public Integer doWork(Double arg) {
return arg.intValue();
}
}
// ...this has all kinds of autoboxing madness, but...
public static class F2 implements Function<Integer, Double> {
@Override
public Integer doWork(Double arg) {
double ceil = Math.ceil(arg);
return (int) ceil;
}
}
// ...why you'd want to do something like this is quite beyond me...
public static class G1 implements Function<Double, String> {
@Override
public Double doWork(String arg) {
return Math.PI * arg.length();
}
}
// ...ditto this...
public static class G2 implements Function<Double, String> {
@Override
public Double doWork(String arg) {
return Math.E * arg.length();
}
}
// oh, yeah, it was so we could test this weird thing
@Test
public void testCollateOrSomething() {
List<String> data = Arrays.asList("x", "xx", "xxx");
List<Function<Integer, Double>> fList = Arrays.asList(new F1(), new F2());
List<Function<Double, String>> gList = Arrays.asList(new G1(), new G2());
List<Integer> results = SomethingWeird.collateOrSomething(data, fList, gList);
assertEquals(12, results.size());
// x
assertEquals(3, (int) results.get(0));
assertEquals(2, (int) results.get(1));
assertEquals(4, (int) results.get(2));
assertEquals(3, (int) results.get(3));
// xx
assertEquals(6, (int) results.get(4));
assertEquals(5, (int) results.get(5));
assertEquals(7, (int) results.get(6));
assertEquals(6, (int) results.get(7));
// xxx
assertEquals(9, (int) results.get(8));
assertEquals(8, (int) results.get(9));
assertEquals(10, (int) results.get(10));
assertEquals(9, (int) results.get(11));
}
}