views:

175

answers:

6

Introducing some of the goodness of collection operations to our codebase without adding a new external library dependency, we are adding these methods to our utility package.

static public List<T> filter(List<T> source, Predicate<T> filter);
static <Y,T> public List<Y> transform(List<T> source, Mutator<Y,T> filter);
static public boolean exists(List<T> source, Predicate<T> filter);
static public T findFirst(List<T> source, Predicate<T> filter);
static public boolean trueForAll(List<T> source, Predicate<T> filter);

With the attendant interfaces

public interface Predicate<T> { public boolean apply(T item); }
public interface Mutator<T,Y> { public Y apply(T item); }

So the questions:

  • Is Filters a good name for the class containing the extensions? If not, a better?
  • Is Mutator<T,Y> appropriately named?
  • Should I prefer map to transform and reduce to filter?
  • Are there any important set-based functions that I've forgotten to include in the library class?

Edited to add: A significant argument I have against map (and thus in favor of transform) is that map has significant semantic load due to the many uses for java.util.Map

A: 

This isn't really what you asked, but it's in the spirit of your question. To me, it reads better to say:

List<String> shortWords = filtered(allWords, short);

than

List<String> shortWords = filter(allWords, short);

I would stick with transform and filter.

Carl Manaster
I would tend to disagree; I think the verb works a little clearer than the adjective (because it more accurately describes the fact that some action is occurring). It's a minor disagreement, though.
McWafflestix
I tend to think of methods as actions. filter seems more appropriate than filtered. The important thing is to be consistent though.
ebrown
Carl Manaster
+1  A: 

This looks really nice; I think you're definitely on the right track here. Yes, I think Mutator is a good name; transform is better because it's more commonly read as a verb, and map has a "noun" connotation that might be confusing; and the only major set-based function that I could think that you might want would be a reordering function.

McWafflestix
since Collections.sort is available, I didn't think we needed an additional sorting method.
Tetsujin no Oni
+1  A: 

in a similar library I used:

  • Specification in place of Predicate: aSpecification.isSatisfiedBy(anObject);
  • Mapper in place of Mutator
  • map is collect for smalltalkers (transform in your case)
  • fold is inject for smalltalkers
  • filter is select for smalltalkers
dfa
fold? what's the underlying operation there?
Tetsujin no Oni
http://c2.com/cgi/wiki?FoldFunction
dfa
+1  A: 

I would call them map and filter. Reduce has a slightly different meaning for me, and transform is too vague. As for the class name, Filters may not be the best, but I don't have a better recommendation.

I know you weren't asking for this specifically, but some of the signatures in the generic methods can be improved:

 static public <T> List<T> filter(List<T> source, Predicate<? super T> filter);
 static public <Y,T> List<Y> transform(List<T> source, Mutator<Y,? super T> filter);
 static public <T> boolean exists(List<T> source, Predicate<? super T> filter);
 static public <T> T findFirst(List<T> source, Predicate<? super T> filter);
 static public <T> boolean trueForAll(List<T> source, Predicate<? super T> filter);
waxwing
Thanks, since I'm used to thinking in CLR generics rather than JDK5 generics, it's definitely a good point.
Tetsujin no Oni
A: 

It would seem Transform should be Mutate (or alternatively Mutator should be Transformer,) for consistency's sake. This seems fairly clear about the intent:

static <Y,T> public List<Y> mutate (List<T> originalForm, Mutator<Y,T> mutator);

It is also a bit more verbose (but more consistent and conventional) to spec:

static public boolean isTrueForAll(List<T> source, Predicate<T> filter);

or

static public boolean assertTrueForAll(List<T> source, Predicate<T> filter);
good point about isTrueForAll vs. trueForAll ... (but I have to admit coming at this from the "what's missing from JDK1.5 collections that is present in the .Net BCL" perspective, so my naming expectation had a preexisting bias...
Tetsujin no Oni
+2  A: 

Are there any important set-based functions that I've forgotten to include in the library class?

For higher-order collection functions I use the approach outlined by Adrian Kuhn in his article "Pimp My Foreach".

Some of these you've already got, but thought I'd throw them out there anyway:

  • AllSatisfy
  • AnySatisfy
  • Cardinality
  • Collect
  • Count
  • CutPieces
  • Detect
  • Fold
  • GroupedBy
  • IndexOf
  • Inject
  • Reject
  • Select
cwash