Method-Object pairs in Java
I'd like to create a list of method-object pairs. Each method is a fun开发者_StackOverflow社区ction returning a boolean. Then:
foreach(pair) {
if method evaluates to true {
do something with the object
}
}
One way of modelling this that I can think of is to have a class Constraint
with a method isValid()
and for each constraint produce an anonymous class (overriding the isValid()
method). I feel like there could be a nicer way. Can you think of any?
In Java there are no method pointers, so the only (better) way of doing this is using a common Interface as you said:
public interface Constraint {
boolean isValid();
}
This way you can create a map (or a List of Tuple, as you wish), iterate over the elements, call the Constraint isValid method and perform the operation based on the response:
public void doThings(Map<Constraint, Object> map) {
for (Entry<Constraint, Object> entry: map.entrySet()) {
if (entry.getKey().isValid()) {
Object obj = entry.getValue();
// Do whatever you want with the object
}
}
}
Hope it helps.
Regards!
Program through an interface that you implement with your class:
package test;
public interface Constraint {
boolean isValid();
}
Use the interface as your variable and it doesn't matter what class is in the list as long as it implements the interface. Program to interfaces...
package test;
import java.util.LinkedList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Constraint> list = new LinkedList<Constraint>();
list.add(new A());
list.add(new B());
for (Constraint con : list) {
if (con.isValid()) {
System.out.println("True");
}
else {
System.out.println("False");
}
}
}
}
class A implements Constraint {
@Override
public boolean isValid() {
return false; // add real code for valid check
}
}
class B implements Constraint {
@Override
public boolean isValid() {
return true; // add real code for valid check
}
}
Have a look at Google's Guava library. It already contains 2 interfaces that may interest you.
The Predicate is an interface that is very similar to what you are doing with Constraint. Instead of isValid() it has a method called apply() which returns a boolean to indicate whether or not something should be done to the object passed in. This is paired with other collection functions within the Guava library to perform (or not perform) operations on entire collections. Which is exactly what you appear to be doing with your for:each loop.
The Function interface may interest you as well, but only because you brought up Function pointers. I think the Predicate interface with some of the other collection classes in Guava will do exactly what you need in a minimal amount of readable code.
An example of this would be:
for(Pair pair : Collections2.filter(pairs, pairPredicate)){
// Do something. All pairs that get to this point have been validated
}
This would be easier in Java if functions were first class objects, but your approach of returning an anonymous class will work. I think a cleaner approach however is the Domain Driven Design specification pattern. The idea is defining an interface:
interface Specification {
boolean isSatisfiedBy(Criteria criteria)
}
interface Criteria {
/* what goes on here is up to you */
}
This would let you iterate through say a collection of Specification
entities as:
for (Specification s : specifications) {
if (!s.isSatisfiedBy(criteria) { continue; }
/* do something */
}
精彩评论