Chapter 4. Functors

Introduction

The American Heritage Dictionary defines a functor as “one that performs an operation or a function,” and, in the context of programming, a functor is an object that encapsulates “functional logic”—a functional object. So with a definition as abstract as “something that does stuff,” you won’t find a lot of satisfying, concise explanations of what a functor can do; in the abstract, anything that performs an operation or function could be considered a functor, and the process of drawing divisions between what should and should not be implemented with functors becomes a matter of personal preference. I’m not going to attempt to give a well-polished, textbook definition of a functor; this chapter simply demonstrates the set of basic functors from Commons Collections. Functors are less of an impressive new technology and are more of an approach to programming. Even if you are unfamiliar with the term, you’ve likely used functors without realizing it; two functors in common usage are Comparator and Iterator.

Both Comparator and Iterator serve to isolate an algorithm; Comparator encapsulates logic to compare two objects, and Iterator encapsulates logic used to iterate over a collection of objects. Functors often lead to more code reuse and a cleaner design because functional logic can be abstracted and extracted out of logic dealing with a specific data structure. For example, to compare two Person beans, you could make the Person class implement Comparable and provide a compareTo() method in the Person class, or you could write a PersonComparator, separating the comparison logic from the Person class. It is this separation of functional logic and the ability to combine functors together that make functors an interesting solution to a number of problems, from the creation of a Closure pipeline to a series of Predicate objects used to model a digital logic circuit.

Jakarta Commons Collections 3.0 introduces a set of functor interfaces in the org.apache.commons.collections package: Predicate, Transformer, Factory, and Closure objects. Predicate objects evaluate criteria or conditions, returning a boolean result. Transformer objects create a new object based on an input object, Closure objects act on an input object, and Factory objects create objects. The powerful part of functors isn’t that Commons Collections has introduced a few new interfaces—the power is only evident once you realize how they can be used in concert with other Jakarta Commons utilities such as Commons BeanUtils and Commons Collections. Chapter 5 makes heavy use of the functors introduced in this chapter, and Chapter 3 discusses a BeanComparator and a BeanPredicate.

This chapter focuses on the functors introduced in Commons Collections 3.0 and also deals with improvements to the Comparator interface. Commons Collections introduces some improvements to the Iterator interface, but, since people usually use Iterator objects with Collections, recipes involving Iterator objects are in the next chapter, which covers Java Collections. Functors, part of Commons Collections, are somewhat misplaced, and, even as this chapter is written, a Commons Functor project is being finalized in the Jakarta Commons Sandbox. By the time you read this chapter, the Commons Functor project may have been released. This book assumes that you are using the functors available in the 3.0 release of Commons Collections. The Commons Functor release contains a number of changes and improvements to the set of functors introduced in Commons Collections 3.0, and, when possible, the See Also sections in each recipe discuss the relevant class or interface in the fast-developing Commons Functor project.

Get Jakarta Commons Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.