Uploaded image for project: 'Commons Collections'
  1. Commons Collections
  2. COLLECTIONS-290

AllPredicate should be able to cast objects

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 3.2
    • 4.x
    • Functor
    • None

    Description

      When using the generified AllPredicate class (in it's current form), it requires instantiation with all predicates having generic supertypes of the resultant combination:

      public static <T> Predicate<T> getInstance(Predicate<? super T> ... predicates)

      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:

      public final class InstanceofPredicate<T,CT> implements Predicate<T>, Serializable
      ...
      public static <T,CT> InstanceofPredicate<T,CT> getInstance(Class<CT> type) 

      Where CT is the Type of the class that will be matched by the predicate.
      AllPredicate should have constructors like:

      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)

      This would allow far nicer constructs of anonymous or simple predicates, and better type safety.

      There would also be an additional method on AllPredicate:

      public CT cast(Object matched)

      That could be used as follows:

      Predicate<Integer> predicate = AllPredicate.instanceOf(Integer.class, ...);
      Object o= ...;
      if (predicate.evaluate(o)){
          Integer i = predicate.cast(o);
           //perform action
      }

      Alternatively there could be a different method that attempts to coerce the type:

      public CT transform(T t){
          if (evaluate(t)){
              return clazz.cast(t);  //clazz is of type Class<CT>
          }
          return null;
      }

      This could be used as follows:

      Predicate<Integer> predicate = AllPredicate.instanceOf(Integer.class, ...);
      Object o= ...;
      Integer i = predicate.transform(o)
      if (i != null){
          //perform action
      }

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

      Attachments

        Activity

          People

            shammah Stephen Kestle
            shammah Stephen Kestle
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:

              Time Tracking

                Estimated:
                Original Estimate - 4h
                4h
                Remaining:
                Remaining Estimate - 4h
                4h
                Logged:
                Time Spent - Not Specified
                Not Specified