Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Predicate Searching in Java

Not quite sure how to word this question. I am wondering if there is a method to check certain parts of a custom java class to see if it matches a certain criteria. Such as this

public Name(String forename, String middlename, String surname)

And then when an array of instances of that class are created say,

Name[] applicants = new Name[4];

applicants[0] = new Name("john","bob", "rush");
applicants[1] = new Name("joe","bob", "rushden");
applicants[2] = new Name("jack","bob", "rushden");
applicants[3] = new Name("jake","bob", "rushden");

Is it possible to do a search over the instances of the class for person with

midddlename.equals("bob") && surname.equals("rush")

I am not really looking for a solution that is if(surname.equals("bob")) then else,etc

But more a in-built java class that allows for rapid searching over the array. the speed of this is very important.

like image 938
pie154 Avatar asked Feb 25 '10 17:02

pie154


2 Answers

There isn't built in support, but Apache Collections and Google Collections both provide Predicate support over collections.

You may find this question and its answers helpful. Same with this developer.com article.

e.g. Using Google Collections:

final Predicate<name> bobRushPredicate = new Predicate<name>() {
   public boolean apply(name n) {
      return "bob".equals(n.getMiddlename()) && "rush".equal(n.getSurname());
   }
}

final List<name> results = Iterables.filter(applicants, bobRushPredicate));
like image 86
Mike Avatar answered Oct 19 '22 23:10

Mike


Streams and lambda

Java 8 added lambda expressions and the stream API, so support is built-in now.

Name[] applicants = new Name[4];

applicants[0] = new Name("john", "bob", "rush");
applicants[1] = new Name("joe", "bob", "rushden");
applicants[2] = new Name("jack", "bob", "rushden");
applicants[3] = new Name("jake", "bob", "rushden");

Optional<Name> result = Arrays.stream(applicants)
    .filter(name -> name.middlename.equals("bob") && name.surname.equals("rush"))
    .findAny();
    
result.ifPresent(name -> System.out.println(name));

There are lots of options available here. You can get the first name to match by switching .findAny() to .findFirst() or run the search in parallel by inserting .parallel() after .stream(applicants), for example.

like image 24
Andrew Avatar answered Oct 19 '22 23:10

Andrew