| |
jga: Generic Algorithms for Java | License: | GNU Library or Lesser General Public License (LGPL) | URL: | http://jga.sf.net/ | Description: | |
Package Name | Comment | net.sf.jga.algorithms |
Provides common algorithm implementations over arrays, collections and other
iterable resources, and iterators.
| net.sf.jga.fn |
Provides base definitions for Functors, Predicates, Visitors.
| net.sf.jga.fn.adaptor |
Provides Functors that allow assembly of primitive functors into compound
structures.
| net.sf.jga.fn.algorithm |
Provides utilities that apply Functors and Predicates to common situations.
| net.sf.jga.fn.arithmetic |
Provides simple arithmetic Functors for Number classes.
Implementation is provided by a set of adaptor objects that implement the
Arithmatic interface. Adaptors are provided for all standard Number classes:
the six Reference classes in the java.lang package (Byte, Short, Integer,
Long, Float, and Double) and the two classes defined in the java.math package
(BigInteger and BigDecimal).
To apply the Functors found in this package with user-defined Number
implementations, it is necessary to create and register an implementation of
Arithmetic or IntegerArithmetic. For example, assuming that a
Fraction class has been defined, support for arithmetic operations
could be provided by
public class FractionMath implements Arithmetic<Fraction> {
public Fraction plus (Fraction x, Fraction y) {
// implementation omitted
}
...
}
Before any Functors can be built using the Fraction class, it is necessary to
register the FractionMath implementation with the ArithmeticFactory.
ArithmeticFactory.register(Fraction.class, new FractionMath());
| net.sf.jga.fn.comparison |
Provides Functors and Predicates that compare values of various types.
As of the 0.6 release, this package is in a state of transition. The forces
at work are
- the comparision mechanism in Java, ie, the Comparable and Comparator
interfaces.
- a desire to simplify the design so that a particular comparison method,
eg, Less, is embodied in a single class.
- a desire to preserve type-safety.
- a desire to preserve convenience of default constructors.
In the previous releases, there were two functors that provided for a
single comparison method -- one that was restricted to
Comparable arguments, and one that used (and therefore
required at construction) a Comparator. There was no
relationship between the restricted version, which was named for the
specific comparison operator (ie, Less.java) and the version
that required a Comparator, which was named with a
'-Comp' suffix (ie, LessComp.java).
To create a relationship between the two versions would have required
that the '-Comp' version be the base class. To derive the
-Comp version from the Comparable version would have
had the effect of imposing a restriction in the base class that the
derived class relaxes (this violates substitutabiliy).
Ideally, there would be one class: it would have to use a
Comparator as implementation in order to be universally
applicable, but the default constructor could provide some sort of
default Comparator. Unfortunately, there really is no useful
comparator that can be applied globally. The most common case that we
can support, however, would be that Comparable objects be
compare via their compareTo() method, as the
ComparableComparator does. For this to work, we would need
to ensure that the default constructor could only be called when the
parm type of the functor implements Comparable. Java cannot
enforce this restriction.
What we can do is define a subclass that has a more
restrictive bound than the base class. Throughout this package,
classes that need to support Comparable objects via a default
Comparator define a public static subclass that imposes the
additional generic bound and provides the correct default constructor.
I've created a convention by which all of the subclasses are named for
the bound they impose, so in this package, to use a comparison
operator for Comparable types requires the use of the
Comparable subclass. For example, to compare some arbitrary
class for which a Comparator is available, you might use a
Less object, and pass the Comparator at
construction. To compare String objects, you would use
Less.Comparable, whose default constructor passes a default
Comparator to the base Less constructor.
So, the upshot of all this is that in the next release, we will be
able to partially resolve the competing forces. The comparison
functors will support all types of java objects using both comparison
mechinisms with a single primary class for each comparison operation
(the nested subclasses are de-emphasized -- they are an unfortunate
implementation detail necessary to work around a limitation in generic
java). The final versions preserve type-safety and the cost in
inconvenience is not too great, as there is still a default
constructor, it has simply been moved to the nested subclass in order
to restrict its usage to appropriate generified types. In the next
release:
- The default constructor in the base classes will be removed.
- The '-Comp' versions will be removed.
Both of these changes are deferred for one release in order to avoid
breaking code without warning.
| net.sf.jga.fn.logical |
Provides Functors and Predicates that implement boolean logic.
The LogicalAnd, LogicalOr, and LogicalNot predicates operate on Boolean values.
The others are Predicates that operate on the results of child predicates,
generally passed to their constructors.
| net.sf.jga.fn.property |
Provides Functors and Predicates that operate on Java Objects that observe
the bean standard naming convention. This is the home for functors that use
reflection in construction and/or evaluation.
In previous versions, the constructors used in this package created type-unsafe
functors. This was due to an incomplete understanding on my part of the
implications of parameterizing the Class class. It's somewhat more obvious
to me know how clever this is: it allows the compiler to check that the class
given to a method is in fact the same class with which the functor is
parameterized. The previous constructors did not take the class of the
argument, or they used unparameterized classes as arguments: they typically
performed some reflection on the first argument passed to fn(), lazily
loading the Method or Constructor on the first call.
In this version, those constructors are deprecated. They are likely to
disappear in a future version (unless they prove necessary to the success
of some of the project goals).
| net.sf.jga.fn.string |
Provides Functors and Predicates that operate on Strings.
| net.sf.jga.parser |
Parser that allows expressions of an as-yet unnamed Java-like language
to be parsed to create functors.
The langauge is a subset of a Java 1.5 grammar, whose BNF form is
available here. While it is an incomplete subset
of the Java expression syntax, what's already implemented is enough
to be interesting. You can do basic arithmetic (with all standard
Number implementations, including BigDecimal and BigInteger),
relational comparisons, shifts, boolean expressions, conditionals,
call constructors and methods, reference member variables, cast
values, test instanceof, and reference class constants (including
enumerated values when run on Java 1.5). Essentially, the grammar
allows anything that can be typed on the right side of a Java
assignment statement.
The following expression syntax is not implemented in the current release.
- arrays
- numeric coercion (arithmetic and relational operands must cast if necessary)
- Nested class constructor calls (ie, the rarely used "foo.new bar()" syntax)
- assignments or assignment forms (i.e.: +=, -=, etc)
- pre- or post- increment or decrements
- anonymous class creation
| net.sf.jga.swing |
Provides implementations of standard Swing models, editors, and renderers
that use Functors as a means of varying behaviour. The intent of this package
is to allow for many common patterns of usage to be accomplished without
having to create boilerplate classes.
For example, JTables are frequently used as little more than multi-column list
controls: they are configured to be non-updatable, and are used solely as a
source of selection events. They're used in this way because they are more
powerful than JList controls in the range of display logic that they support.
Configuring tables in this way usually requires a fairly boilerplate TableModel
implementation.
GenericTableModel allows the programmer to build a TableModel from a list of
data and a few functors. This is intended to eliminate (or at least greatly
reduce) the boilerplate coding.
The classes in this package are at varying degrees of completeness, and more
classes are expected to be added here in the coming releases. There will be
classes for use with JTrees for example, and more Renderer and possibly Editor
classes are likely.
Other Possible entries in this package
- FilteredListModel
- uses a functor to determine which entries in a list
will be visible.
- GenericNumberFormatter
- similar to NumberFormatter except that all
java.lang.Number implementations can be supported (even those that are user
supplied). Specifically, it will include BigDecimal (NumberFormatter does not
support BigDecimal).
- GenericFormatter
- DefaultFormatter implementation that allows the use of
a pair of functors to use in the stringToValue and valueToString
implementations.
- OutlineTreeModel
- wraps a list model, provides nodes based on a set of
functors that retrieve/compute properties of the values in the list
| net.sf.jga.swing.spreadsheet |
Provides Spreadsheet Widget based on a sparse matrix of jga functors,
and several application level classes designed to present the widget
in various guises. The widget uses functors both for calculation and
for interaction with the environment: the contents of the cell as well
as its format, and several key capabilities typically provided by
applications (but not necessarily required of Swing widgets; eg,
document reading/writing, user prompting and notifications, feedback,
etc).
The various application objects each configure the widget to provide
an application appropriate for various forms: standalone application
(single document only), applet, Web Start, ... The Widget is broken into
two logical pieces: a Swing JComponent derivitive that can be added to
any application with minimum fuss, and a Controller class that provides
a collection of utilities that allow the individual application wrappers
to configure the widget.
| net.sf.jga.util |
Provides Facade objects for working with the algorithm functors, and a variety
of utility iterators for various purposes.
The functionality that is adapted from STL is provided by a set of functors in
the net.sf.jga.fn.algorithm package operate on iterators. To ease the
transition to this approach, there are two facade objects whose methods
correspond to the algorithms provided by STL.
The first, Algorithms, operates on collections, and is appropriate for getting
easy answers to common questions over collections. The second, Iterators, is
closer conceptually to the implementation, and is more appropriate if the same
function is to be called several times for a given collection. Most of the
methods in these two facades are a single logical statement (although sometimes
the singe statement is broken up for formatting reasons) that constructs and
invokes the appropriate algorithm functor.
The summary of the functions adapted from STL is as follows:
STL Function name | Facade method name | functor |
accumulate() | accumulate() | Accumulate |
adjacentDiff() | adjacentDiff() | TransformAdjacent(Minus) |
adjacent_find() | findAdjacent() | FindAdjacent |
count() | count() | Count |
count_if() | count() | Count |
equal() | equal() | varies based on form (3) |
find() | find() | Find |
find_first_of() | findElement() | FindElement |
find_if() | find() | Find |
for_each() | forEach() | ForEach (2) |
lexicographical_compare() | lessThan() | varies based on form (3) |
max() | maximum() | Find,MaxValue (4) |
max_element() | maximumValue() | MaxValue [collection] Accumulate [iteration] |
merge() | merge() | Merge |
min() | minimum() | Find,MinValue (4) |
min_element() | minimumValue() | MaxValue [collection] Accumulate [iteration] |
mismatch() | mismatch() | FindMismatch |
remove() | removeAll | n/a(5) |
remove_if() | removeAll | RemoveAll |
remove_copy() | removeAllCopy | RemoveAll(6) |
remove_copy_if() | removeAllCopy | RemoveAll(6) |
replace() | replaceAll | n/a(5) |
replace_if() | replaceAll | ReplaceAll |
replace_copy() | replaceAllCopy | ReplaceAll(6) |
replace_copy_if() | replaceAllCopy | ReplaceAll(6) |
search() | match() | FindSequence |
search_n() | findRepeated() | FindRepeated |
transform (unary form) | transformCopy | TransformUnary |
transform (binary form) | transformCopy | TransformUnary |
unique() | unique | n/a(5) |
unique_copy() | uniqueCopy | Unique(6) |
(2) - The ForEach functor returns the result of the final call to the
given functor, where the method returns the given functor.
(3) - The comparison operations are not implemented in terms of
functors found in net.sf.jga.fn.algorithm: they are generally implemented via
Comparators defined in net.sf.jga.util and comparison functors from
net.sf.jga.fn.comparison.
(4) - Only supported for collections, not for iterations. Again, we'd
need to be able to clone iterators in order to support them.
(5) - Works with Lists only (not general Collections). The only option
available for updating in place is via a ListIterator.
(6) - Unlike C++, the X_copy forms append to the output collection,
instead of overwriting it. In C++, the implementations can't assume the right to
enlarge the output collection (it might be an array or some other fixed size
structure) while in Java, the collections aren't inherently fixed size (if the
user passes a fixed size or capped size collection to one of these methods, we'll
pass through the appropriate exception, if necessary)
|
|