[ 
https://issues.apache.org/jira/browse/COLLECTIONS-290?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14019264#comment-14019264
 ] 

Thomas Neidhart commented on COLLECTIONS-290:
---------------------------------------------

A simpler way might be to add the following factory method:

{noformat}
    public static Predicate<Object> allPredicate(final Predicate<Object> p1, 
final Predicate<?>... predicates) {
        FunctorUtils.validate(p1);
        FunctorUtils.validate(predicates);
        if (predicates.length == 0) {
            return p1;
        }

        Predicate<Object>[] copy = new Predicate[1 + predicates.length];
        copy[0] = p1;
        System.arraycopy(predicates, 0, copy, 1, predicates.length);
        return new AllPredicate<Object>(copy);
    }
{noformat}

The idea is that if the first predicate takes Object as input like an 
InstanceOfPredicate, we know that the resulting AllPredicate will have the 
generic type Object.

Imho this is equally good to just use raw types in this case but would save the 
user of various compiler warnings.

An example usage would be like this:

{noformat}
        Predicate<Object> p1 = 
InstanceofPredicate.instanceOfPredicate(Integer.class);
        Predicate<Integer> p2 = new Predicate<Integer>() {

            @Override
            public boolean evaluate(Integer object) {
                return object.intValue() < 5;
            }
            
        };
        Predicate<Object> all = AllPredicate.allPredicate(p1, p2);
        System.out.println(all.evaluate(Integer.valueOf(3)));
{noformat}

The InstanceOfPredicate basically serves as a filter for the following 
predicates to prevent class cast exceptions during runtime.

> AllPredicate should be able to cast objects
> -------------------------------------------
>
>                 Key: COLLECTIONS-290
>                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-290
>             Project: Commons Collections
>          Issue Type: Improvement
>          Components: Functor
>    Affects Versions: 3.2
>            Reporter: Stephen Kestle
>            Assignee: Stephen Kestle
>             Fix For: 4.x
>
>   Original Estimate: 4h
>  Remaining Estimate: 4h
>
> When using the generified AllPredicate class (in it's current form), it 
> requires instantiation with all predicates having generic supertypes of the 
> resultant combination:
> {code}public static <T> Predicate<T> getInstance(Predicate<? super T> ... 
> predicates){code}
> However, if one of the predicates was an InstanceOfPredicate, it could mean 
> that every other predicate is able to be a super of the type that the 
> instanceOfPredicate returns true for.
> I propose that InstanceOfPredicate has a signature like:
> {code}public final class InstanceofPredicate<T,CT> implements Predicate<T>, 
> Serializable
> ...
> public static <T,CT> InstanceofPredicate<T,CT> getInstance(Class<CT> type) 
> {code}
> Where CT is the Type of the class that will be matched by the predicate.
> AllPredicate should have constructors like:
> {code}public static <T,CT> AllPredicate<T,CT> 
> getInstance(InstanceOfPredicate<?,CT>, Predicate<? super CT> ... predicates)
> public static <T,CT> AllPredicate<T,CT> getInstance(Class<CT>, Predicate<? 
> super CT> ... predicates){code}
> This would allow far nicer constructs of anonymous or simple predicates, and 
> better type safety.
> There would also be an additional method on AllPredicate:
> {code}public CT cast(Object matched){code}
> That could be used as follows:
> {code}Predicate<Integer> predicate = AllPredicate.instanceOf(Integer.class, 
> ...);
> Object o= ...;
> if (predicate.evaluate(o)){
>     Integer i = predicate.cast(o);
>      //perform action
> }{code}
> Alternatively there could be a different method that attempts to coerce the 
> type:
> {code}public CT transform(T t){
>     if (evaluate(t)){
>         return clazz.cast(t);  //clazz is of type Class<CT>
>     }
>     return null;
> }{code}
> This could be used as follows:
> {code}Predicate<Integer> predicate = AllPredicate.instanceOf(Integer.class, 
> ...);
> Object o= ...;
> Integer i = predicate.transform(o)
> if (i != null){
>     //perform action
> }{code}
> I prefer the cast() method; however, it would not re-evaluate the object, so 
> would need documentation to be used correctly.  The second method would allow 
> it to be used as a transformer, but would substitute boolean checking to null 
> checking.
> Perhaps both  are warranted.  (The reason for the convenience methods are to 
> not generate type-coercion warnings).



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to