How to filter a Collection<String>
using lambdaj and the String.matches method.
I'm new to lambdaj and feeling dumb since the examples given are more complicated than this.
3 Answers
If it were possible to do it using the having(on(...))
construct, the call could look like this:
select(collection, having( on(String.class).matches("f*") ))
But unfortunately it is not possible, because the String
class is final and so on(String.class)
is unable to create the proxy required by the having
matcher.
Although hamcrest brings no regex matcher, you don't have to write your own. The net offers several implementations. I'd like to see such a matcher in a ready-to-use public library, which I could simply include as dependency, instead of having to copy the source code.

- 8,913
- 2
- 32
- 39
If you want to filter a Collection you can do as described below:
@Test
public void test() {
Collection<String> collection = new ArrayList<String>();
collection.add("foo");
collection.add("bar");
collection.add("foo");
List<String> filtered = select(collection, having(on(String.class), equalTo("foo")));
assertEquals(2, filtered.size());
}

- 4,373
- 8
- 43
- 56
-
Thanks...I guess I'm still in disbelief that 1. The syntax is so verbose and 2. I have to write my own matcher to boot, since there appears to be no regex matcher in hamcrest. – wytten Apr 06 '12 at 14:25
This works, but I'm not happy that it takes this much code to replace a simple for loop. I prefer "filter" over "select" because it makes the code simpler, and easier to read I think.
public Collection<String> search(String regex) {
List<String> matches = filter(matches(regex), dictionary);
return matches;
}
static class MatchesMatcher extends TypeSafeMatcher<String> {
private String regex;
MatchesMatcher(String regex) {
this.regex = regex;
}
@Override
public boolean matchesSafely(String string) {
return string.matches(regex);
}
public void describeTo(Description description) {
description.appendText("matches " + regex);
}
}
@Factory
public static Matcher<String> matches(String regex) {
return new MatchesMatcher(regex);
}

- 2,800
- 1
- 21
- 38
-
1Well, it requires that much code *once*. I added a regex matcher to my unit test library, so I don't have to write it again. If I ever use matchers in production code, I'll just move the regex matcher to an appropriate library. As noted in my answer, I'd like to see this matcher in a ready-to-use public library. – Christian Semrau Apr 11 '12 at 19:08