Discussion:
[collections] ListUtils.predicatedList() throws IllegalArgumentException
Moritz Petersen
2002-10-26 11:18:59 UTC
Permalink
Hi, am I getting it wrong? I want to create a predicatedList, my code
is like this:

predicatedList = ListUtils.predicatedList(list, new
MyPredicate());

The list already contains some elements.
I would expect, that the predicatedList is some sort of a filtered List
of my original list. MyPredicate.evaluate() returns true or false,
which I believe is the expected behaviour. true, if the object should
appear in the predicatedList and false if it doesn't.
But the following exception is thrown:

java.lang.IllegalArgumentException: Cannot add Object - Predicate
rejected it
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.vali
date(CollectionUtils.java:862)
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.<ini
t>(CollectionUtils.java:844)
at
org.apache.commons.collections.ListUtils$PredicatedList.<init>(ListUtils
.java:218)
at
org.apache.commons.collections.ListUtils.predicatedList(ListUtils.java:4
59)
at TableDataSource.setFilter(TableDataSource.java:79)
at Controller.search(Controller.java:78)

The affected code in CollectionUtils is:

protected void validate(Object o) {
if (!predicate.evaluate(o)) {
throw new IllegalArgumentException("Cannot add Object -
Predicate rejected it");
}
}

which makes me wonder why this validation should throw an exception and
not just return true or false. So I believe I haven't understood how
Predicates work. Looking at the test cases, don't make the situation
more clear to me, because there are some "BlukTests" used, which make
the testing process cryptic. Usually I can learn a lot by looking at
test cases, but in this case, I don't see how the predicatedList()
method is completely tested at all. Any explanations are highly
appreciated. Thank you,

-Mo.
Stephen Colebourne
2002-10-26 13:30:17 UTC
Permalink
This is a misunderstanding of the PredicatedList.

ListUtils.predicatedList() returns a list that blocks the addition of new
elements to the list. Thus the list only contains elements that match the
predicate. The blocking of new elements also applies to the initial list
creation, hence your exception.

What you describe would be called ListUtils.filteredList(). ie. a list that
accepts all elements, but hides them when queried. A filteredList() has not
been coded.

Stephen

----- Original Message -----
From: "Moritz Petersen" <***@mac.com>
To: "Jakarta List" <commons-***@jakarta.apache.org>; "Commons Dev Dev"
<commons-***@jakarta.apache.org>
Sent: Saturday, October 26, 2002 12:18 PM
Subject: [collections] ListUtils.predicatedList() throws
IllegalArgumentException
Post by Moritz Petersen
Hi, am I getting it wrong? I want to create a predicatedList, my code
predicatedList = ListUtils.predicatedList(list, new
MyPredicate());
The list already contains some elements.
I would expect, that the predicatedList is some sort of a filtered List
of my original list. MyPredicate.evaluate() returns true or false,
which I believe is the expected behaviour. true, if the object should
appear in the predicatedList and false if it doesn't.
java.lang.IllegalArgumentException: Cannot add Object - Predicate
rejected it
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.vali
date(CollectionUtils.java:862)
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.<ini
t>(CollectionUtils.java:844)
at
org.apache.commons.collections.ListUtils$PredicatedList.<init>(ListUtils
.java:218)
at
org.apache.commons.collections.ListUtils.predicatedList(ListUtils.java:4
59)
at TableDataSource.setFilter(TableDataSource.java:79)
at Controller.search(Controller.java:78)
protected void validate(Object o) {
if (!predicate.evaluate(o)) {
throw new IllegalArgumentException("Cannot add Object -
Predicate rejected it");
}
}
which makes me wonder why this validation should throw an exception and
not just return true or false. So I believe I haven't understood how
Predicates work. Looking at the test cases, don't make the situation
more clear to me, because there are some "BlukTests" used, which make
the testing process cryptic. Usually I can learn a lot by looking at
test cases, but in this case, I don't see how the predicatedList()
method is completely tested at all. Any explanations are highly
appreciated. Thank you,
-Mo.
--
<mailto:commons-user-***@jakarta.apache.org>
Moritz Petersen
2002-10-26 14:03:36 UTC
Permalink
Ah. Ok. My workaround was to use the FilterIterator.
So, what is the predicatedList(List, Predicate) method for? It tests if
all elements of the List match the Predicate. If one fails, the
predicated List is not created. So one needs to use an empty List and
add the elements after the creation. This makes the List parameter
obsolete in my opinion.
Also, throwing an IllegalArgumentException is critical, as long as it
is not well documented. While this exception is used to control the
program flow, I would prefer a boolean return value (add(Object)
returns true, if the List has changed).

-Mo.
Post by Stephen Colebourne
This is a misunderstanding of the PredicatedList.
ListUtils.predicatedList() returns a list that blocks the addition of new
elements to the list. Thus the list only contains elements that match the
predicate. The blocking of new elements also applies to the initial list
creation, hence your exception.
What you describe would be called ListUtils.filteredList(). ie. a list that
accepts all elements, but hides them when queried. A filteredList() has not
been coded.
Stephen
----- Original Message -----
Sent: Saturday, October 26, 2002 12:18 PM
Subject: [collections] ListUtils.predicatedList() throws
IllegalArgumentException
Post by Moritz Petersen
Hi, am I getting it wrong? I want to create a predicatedList, my code
predicatedList = ListUtils.predicatedList(list, new
MyPredicate());
The list already contains some elements.
I would expect, that the predicatedList is some sort of a filtered List
of my original list. MyPredicate.evaluate() returns true or false,
which I believe is the expected behaviour. true, if the object should
appear in the predicatedList and false if it doesn't.
java.lang.IllegalArgumentException: Cannot add Object - Predicate
rejected it
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.va
li
date(CollectionUtils.java:862)
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.<i
ni
t>(CollectionUtils.java:844)
at
org.apache.commons.collections.ListUtils$PredicatedList.<init>(ListUti
ls
.java:218)
at
org.apache.commons.collections.ListUtils.predicatedList(ListUtils.java
:4
59)
at TableDataSource.setFilter(TableDataSource.java:79)
at Controller.search(Controller.java:78)
protected void validate(Object o) {
if (!predicate.evaluate(o)) {
throw new IllegalArgumentException("Cannot add Object -
Predicate rejected it");
}
}
which makes me wonder why this validation should throw an exception and
not just return true or false. So I believe I haven't understood how
Predicates work. Looking at the test cases, don't make the situation
more clear to me, because there are some "BlukTests" used, which make
the testing process cryptic. Usually I can learn a lot by looking at
test cases, but in this case, I don't see how the predicatedList()
method is completely tested at all. Any explanations are highly
appreciated. Thank you,
-Mo.
--
--
Stephen Colebourne
2002-10-26 14:26:43 UTC
Permalink
Post by Moritz Petersen
Ah. Ok. My workaround was to use the FilterIterator.
Yes, makes sense.
Post by Moritz Petersen
So, what is the predicatedList(List, Predicate) method for? It tests if
all elements of the List match the Predicate. If one fails, the
predicated List is not created. So one needs to use an empty List and
add the elements after the creation. This makes the List parameter
obsolete in my opinion.
There are different types of List implementations, not just ArrayList. This
allows the caller to select which to use.
Post by Moritz Petersen
Also, throwing an IllegalArgumentException is critical, as long as it
is not well documented. While this exception is used to control the
program flow, I would prefer a boolean return value (add(Object)
returns true, if the List has changed).
The collections API allows either an IAE, or a return value of false to
indicate that something wasn't added. However, this code chose IAE - it just
seems to make more sense.

If you believe the javadoc of PredicatedList could be improved, please feel
free to submit a patch to commons-dev list.

Stephen
Post by Moritz Petersen
-Mo.
Post by Stephen Colebourne
This is a misunderstanding of the PredicatedList.
ListUtils.predicatedList() returns a list that blocks the addition of new
elements to the list. Thus the list only contains elements that match the
predicate. The blocking of new elements also applies to the initial list
creation, hence your exception.
What you describe would be called ListUtils.filteredList(). ie. a list that
accepts all elements, but hides them when queried. A filteredList() has not
been coded.
Stephen
----- Original Message -----
Sent: Saturday, October 26, 2002 12:18 PM
Subject: [collections] ListUtils.predicatedList() throws
IllegalArgumentException
Post by Moritz Petersen
Hi, am I getting it wrong? I want to create a predicatedList, my code
predicatedList = ListUtils.predicatedList(list, new
MyPredicate());
The list already contains some elements.
I would expect, that the predicatedList is some sort of a filtered List
of my original list. MyPredicate.evaluate() returns true or false,
which I believe is the expected behaviour. true, if the object should
appear in the predicatedList and false if it doesn't.
java.lang.IllegalArgumentException: Cannot add Object - Predicate
rejected it
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.va
li
date(CollectionUtils.java:862)
at
org.apache.commons.collections.CollectionUtils$PredicatedCollection.<i
ni
t>(CollectionUtils.java:844)
at
org.apache.commons.collections.ListUtils$PredicatedList.<init>(ListUti
ls
.java:218)
at
org.apache.commons.collections.ListUtils.predicatedList(ListUtils.java
:4
59)
at TableDataSource.setFilter(TableDataSource.java:79)
at Controller.search(Controller.java:78)
protected void validate(Object o) {
if (!predicate.evaluate(o)) {
throw new IllegalArgumentException("Cannot add Object -
Predicate rejected it");
}
}
which makes me wonder why this validation should throw an exception and
not just return true or false. So I believe I haven't understood how
Predicates work. Looking at the test cases, don't make the situation
more clear to me, because there are some "BlukTests" used, which make
the testing process cryptic. Usually I can learn a lot by looking at
test cases, but in this case, I don't see how the predicatedList()
method is completely tested at all. Any explanations are highly
appreciated. Thank you,
-Mo.
--
--
--
<mailto:commons-user-***@jakarta.apache.org>
Moritz Petersen
2002-10-26 14:42:02 UTC
Permalink
Post by Stephen Colebourne
There are different types of List implementations, not just ArrayList. This
allows the caller to select which to use.
Oh, obviously.
Post by Stephen Colebourne
Post by Moritz Petersen
Also, throwing an IllegalArgumentException is critical, as long as it
is not well documented. While this exception is used to control the
program flow, I would prefer a boolean return value (add(Object)
returns true, if the List has changed).
The collections API allows either an IAE, or a return value of false to
indicate that something wasn't added. However, this code chose IAE - it just
seems to make more sense.
To my mind, using boolean return values improves readability of code
and makes sense as well. Not to speak about performance. Just my € 0.02
;-)
Post by Stephen Colebourne
If you believe the javadoc of PredicatedList could be improved, please feel
free to submit a patch to commons-dev list.
Yep.

-Mo.

Loading...