Guava provider: transforming a collection with each function

Let's say I have a Node class that has a function as an instance variable.

public class Node { private Function<Node, Double> function; ... 

I have a list of these nodes:

 List<Node> nodes = Lists.newLinkedList(); nodes.add(new Node(someFunction)); nodes.add(new Node(someOtherFunction)); 

I can do it:

 public Collection<Double> getValues() { SomeFunction f = new SomeFunction(); return Collections2.transform(nodes, f); } 

Of course, we will iterate over the nodes of the List and apply the function f to each element, for example mapcar.

What I'm trying to do is convert using the function that every Node element has.

So I, even the Supplier, would help.

 class NodeSupplier implements Supplier<Node> { Iterator<Node> iterator; NodeSupplier(Iterable p) { iterator = Iterators.cycle(p); } @Override public Node get() { return iterator.next(); } } 

Then function to get Node.

 class SupplierGetter implements Function<Supplier<Node>, Node> { @Override public Node apply(Supplier<Node> from) { return from.get(); } } 

Then compose them:

 FunctionGetter fg = new FunctionGetter(); NodeSupplier sup = new NodeSupplier(this); // the this class is Iterable Supplier<Function<Node, Double>> supplier = Suppliers.compose(fg, sup); 

But then it gives me a type mismatch when I try to use it:

 Collections2.transform(nodes, supplier); 

he wants suppler.get (), which is called once.

 Collections2.transform(nodes, supplier.get()); 

Is there an easier way?

I saw a mention

 Suppliers.supplierFunction() 

but does not seem to exist in verison r09.

+4
source share
4 answers

I am confused by what you are trying to do ... Supplier here does not seem useful. Each Node has its own Function . You want to transform the Node collection by applying each Node Function to yourself. So, why not just give the Node class some method:

 // may want a better name public Double applyFunction() { return function.apply(this); } 

Then you just transform use Function as follows:

 public Double apply(Node node) { return node.applyFunction(); } 
+2
source

Besides the fact that I also have my doubts about what you are trying to do, the following should achieve what you are asking for:

 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
source

There is a third way to do this without changing the Node class if we assume that Node provides its function through a public getter.

Using an anonymous class:

 public Collection<Double> getValues() { return Collections2.transform(nodes, new Function<Node, Double>() { @Override public Double apply(Node node) { return node.getFunction().apply(node); } }); } 

Using a singleton enumeration pattern (which I prefer, as it is clearer) :

 public Collection<Double> getValues() { return Collections2.transform(nodes, ApplyNodeFunction.INSTANCE); } /** * A {@link Function} that applies the {@link Node} own function on itself. */ private enum ApplyNodeFunction implements Function<Node, Double> { INSTANCE; @Override public Double apply(Node node) { return node.getFunction().apply(node); } } 
+1
source

The key to my question was the phrase: "So I thought the Supplier would help." The answer is that it is not. I tried to find a use for this - outside the creation of the Map, which, apparently, is its main use. There was the method that I mentioned, but it seems to be the Ministry of Internal Affairs. Perhaps it could be an RFI overload for the tranform to take Iterable as a second parameter

0
source

All Articles