Problem with Predicates.and()

165 views
Skip to first unread message

Sebastian Hoß

unread,
Dec 14, 2009, 11:24:50 AM12/14/09
to Google Collections Library - users list
Hey there,

I'm currently writing a small library and while doing that I deal with
collections quite often. Since I don't want to allow adding any
elements to those collections I enforced certain constraints like in
the following via delegated addXXX and addAllXXX methods:

public boolean addElement(final Type element) {
if (!this.collection.containts(element)) {
if (element != null) {
return this.collection.add(element);
}

throw new NullPointerException("May not add 'null'");
}

throw new IllegalArgumentException("May not add duplicate
elements");
}

Or even more type-related constraints like certain values must be
above a given threshold or whatever. But instead of writing the same
constraints over and over again I thought about a CollectionJoiner
which works similar to the String Joiner class from the google
collections library.

In my current code it looks like this:

join(this.collection).with(element);

With that one can join a given collection with another element/
collection while also checking for the given constraints. In my case
I'm enforcing certain constraints to all collections and elements but
I wanted to add the ability to add extra constraints where needed. For
that I defined a method like the following:

public CollectionJoiner<T> enforce(final Predicate<T>
anotherPredicate) {
this.predicate = Predicates.and(this.predicate,
anotherPredicate);

return this;
}

With that one could write something like this:

join(this.collection).enforce(Predicates.notNull()).with(element);

As you can see I'm now using the Predicate<T> class for my constraints
and I want to "add" the given predicate the already given predicate.
The problem here is that I get a compilation failure when running this
through maven. The debug output is as follows:

[INFO] [compiler:compile {execution: default-compile}]
[DEBUG] Using compiler 'javac'.
[DEBUG] Source directories: [/home/seb/Projekte/Denove/util/src/main/
java]
[DEBUG] Classpath: [/home/seb/Projekte/Denove/util/target/classes
/home/seb/.m2/repository/com/google/collections/google-collections/
1.0-rc5/google-collections-1.0-rc5.jar]
[DEBUG] Output directory: /home/seb/Projekte/Denove/util/target/
classes
[DEBUG] Classpath:
[DEBUG] /home/seb/Projekte/Denove/util/target/classes
[DEBUG] /home/seb/.m2/repository/com/google/collections/google-
collections/1.0-rc5/google-collections-1.0-rc5.jar
[DEBUG] Source roots:
[DEBUG] /home/seb/Projekte/Denove/util/src/main/java
[INFO] Compiling 6 source files to /home/seb/Projekte/Denove/util/
target/classes
[INFO]
------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO]
------------------------------------------------------------------------
[INFO] Compilation failure
/home/seb/Projekte/Denove/util/src/main/java/org/denove/util/
collection/AbstractCollectionJoiner.java:[91,25] cannot find symbol
symbol : method and
(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
location: class org.denove.util.collection.AbstractCollectionJoiner<T>


[INFO]
------------------------------------------------------------------------
[DEBUG] Trace
org.apache.maven.BuildFailureException: Compilation failure
/home/seb/Projekte/Denove/util/src/main/java/org/denove/util/
collection/AbstractCollectionJoiner.java:[91,25] cannot find symbol
symbol : method and
(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
location: class org.denove.util.collection.AbstractCollectionJoiner<T>


at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals
(DefaultLifecycleExecutor.java:715)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle
(DefaultLifecycleExecutor.java:556)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal
(DefaultLifecycleExecutor.java:535)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures
(DefaultLifecycleExecutor.java:387)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments
(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute
(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main
(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:
315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:
430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.CompilationFailureException:
Compilation failure
/home/seb/Projekte/Denove/util/src/main/java/org/denove/util/
collection/AbstractCollectionJoiner.java:[91,25] cannot find symbol
symbol : method and
(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
location: class org.denove.util.collection.AbstractCollectionJoiner<T>


at org.apache.maven.plugin.AbstractCompilerMojo.execute
(AbstractCompilerMojo.java:516)
at org.apache.maven.plugin.CompilerMojo.execute(CompilerMojo.java:
114)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo
(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals
(DefaultLifecycleExecutor.java:694)
... 17 more


The strange thing is that running the same code inside Eclipse during
JUnit tests works fine. The given predicates are picked up and applied
to each new element. And I can somehow work around this issue by
slightly changing the definition of the enforce()-method to the
following:

public CollectionJoiner<T> enforce(final Predicate<T>
anotherPredicate) {
// this.predicate = and(this.predicate,
anotherPredicate);
final Collection<Predicate<T>> predicates = new
ArrayList<Predicate<T>>();
predicates.add(this.predicate);
predicates.add(anotherPredicate);
this.predicate = Predicates.and(predicates);

return this;
}

This works both inside Eclipse and outside in Maven but looks ugly. Is
there something I could do to make my first example compile? I tried
changing the generic type of the Predicate to <? super T> but that
gives me the same compilation failure. Are there any examples on how
to use the Predicates.and() method or any source code I could take a
look at that you know of?

Greets,
Sebastian

Sebastian Hoß

unread,
Dec 15, 2009, 2:10:16 PM12/15/09
to Google Collections Library - users list
On 12/14/2009 05:24 PM, Sebastian Ho� wrote:
>
> ...
>

Writing

Predicates.<T>and(...)

instead of

Predicates.and(...)

fixes this. Thanks to Andrew Myers for pointing this out :-)
Reply all
Reply to author
Forward
0 new messages