假设我有一个Node类,它有一个Function作为实例变量。
public class Node {
private Function<Node, Double> function;
...
我有这些节点的列表:
List<Node> nodes = Lists.newLinkedList();
nodes.add(new Node(someFunction));
nodes.add(new Node(someOtherFunction));
我可以这样做:
public Collection<Double> getValues() {
SomeFunction f = new SomeFunction();
return Collections2.transform(nodes, f);
}
果然,变换遍历节点List并将函数f应用于mapcar等每个元素。
我要做的是让变换使用每个节点元素所具有的功能。
所以我认为供应商会提供帮助。
class NodeSupplier implements Supplier<Node> {
Iterator<Node> iterator;
NodeSupplier(Iterable p) {
iterator = Iterators.cycle(p);
}
@Override
public Node get() {
return iterator.next();
}
}
然后是一个获取节点的函数。
class SupplierGetter implements Function<Supplier<Node>, Node> {
@Override
public Node apply(Supplier<Node> from) {
return from.get();
}
}
然后撰写:
FunctionGetter fg = new FunctionGetter();
NodeSupplier sup = new NodeSupplier(this); // the this class is Iterable
Supplier<Function<Node, Double>> supplier = Suppliers.compose(fg, sup);
但是当我尝试使用它时,它会给我一个类型不匹配:
Collections2.transform(nodes, supplier);
它想要一次调用的suppler.get()。
Collections2.transform(nodes, supplier.get());
有更简单的方法吗?
我看到了提及
Suppliers.supplierFunction()
但在verison r09中似乎不存在。
答案 0 :(得分:2)
我对你要做的事情感到困惑...... Supplier
在这里似乎没用。每个Node
都有自己的Function
。您希望通过将每个Node
的{{1}}应用于自身来转换Node
的集合。那么为什么不给Function
类一些方法:
Node
然后你只需// may want a better name
public Double applyFunction() {
return function.apply(this);
}
使用transform
这样:
Function
答案 1 :(得分:2)
除了我对你要做的事情有疑问之外,以下内容应该达到你的要求:
class Node {
private Function<Node, Double> function;
private static Function<Node,Double> applyFunction = new Function<Node,Double>() {
@Override
public Double apply(final Node input) {
return input.function.apply(input);
}
};
public static Iterable<Double> transform(final Iterable<Node> nodes) {
return Iterables.transform(nodes, applyFunction);
}
}
答案 2 :(得分:1)
如果我们假设Node
通过公共getter公开其函数,则有第三种方法可以在不修改Node类的情况下执行此操作。
使用匿名类:
public Collection<Double> getValues() {
return Collections2.transform(nodes, new Function<Node, Double>() {
@Override public Double apply(Node node) {
return node.getFunction().apply(node);
}
});
}
使用枚举单例模式(我更喜欢,因为它更清晰):
public Collection<Double> getValues() {
return Collections2.transform(nodes, ApplyNodeFunction.INSTANCE);
}
/**
* A {@link Function} that applies the {@link Node}'s own function on itself.
*/
private enum ApplyNodeFunction implements Function<Node, Double> {
INSTANCE;
@Override public Double apply(Node node) {
return node.getFunction().apply(node);
}
}
答案 3 :(得分:0)
我的问题的关键是这句话:“所以我认为供应商会有所帮助。”答案是它没有。我试图找到它的用途 - 在Map创建之外,这似乎是它的主要用途。我提到过一种供应商方法,但似乎是MIA。也许这可能是一个RFI for tranform被重载以将Iterable作为第二个参数