commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Thomas Neidhart (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (COLLECTIONS-290) AllPredicate should be able to cast objects
Date Thu, 05 Jun 2014 20:54:04 GMT

    [ 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)

Mime
View raw message