Lazy Collection in Java

Consider a problem in which I design a tree similar to a collection.

One of the main functions of my collection is to track all saved items one at a time, and then call the specified function for each item until this criterion is there (lazy collection).

Thus, the function must have the following signatures:

void Trace(function func, criteria crit) { item i = firstItem(); while (i != endItem()) { i = nextItem(); func(i); if (crit(i)) return; } } 

in C++ function pointers can be used for func and crit .
I believe the C# , yield keyword is exactly the solution that I think.

How can I get the same thing in Java?

+6
source share
4 answers

In Java, you will pass references to class objects that implement applicable functions, or instead of using Commons Collections:

For instance:

 Closure c = new Closure() { public void execute(Object obj) { ... } }; Predicate p = new Predicate() { public boolean evaluate(Object obj) { ... } } Trace(c, p); 
+2
source

What you are looking for here is a Strategy design template.

The purpose of this template is to drop the implementation of the algorithm into a strategy object. Here, your algorithms are the func and crit functions that you want to pass.

So, you will have an interface called TraceStrategy . You will then pass the implementations of this interface to your collection. Then your code would look like

 void Trace(TraceStrategy traceStrategy) { item i = firstItem(); while (i != endItem()) { i = nextItem(); traceStrategy.func(i); if (traceStrategy.crit(i)) return; } } 

and

 interface TraceStrategy { public boolean crit(item i); public void func(item i); } 

You probably want to make this generic so that you are not tied to item ... but you understand this idea.

+2
source

Create an interface that declares methods and will require a reference to an object that implements the interface as an argument. The caller can create an object using an anonymous inner class.

+1
source

You can make this trace function very simple in Java by combining several methods:

  • Instead of "function pointers," your func and crit should be object instances that implement a specific interface. Then you can call the function on this interface on object i . This is essentially a Vistor Pattern with two different vistor options.
  • You also need to cross the tree somehow. You can implement Iterator - this gives you a good way to go through the whole structure. Alternatively, you can make trace recursive (it calls itself on the left and right branches of the tree), and then you don't need an iterator.

The iterator version will look something like this:

 public void trace(IFunction func, ICriteria crit) { for (T i: this) { func.call(i); if (crit.test(i)) return; } } 

Here T is the type of the collection item, and call and test are the function definitions in the IFunction and ICriteria respectively.

+1
source

All Articles