If you want to create a complex filter without writing extensive java code or xml then you need the, perhaps slightly missnameed, ExpressionBuilder to parse a plain text string.
To create a lessthan filter, the sum total of the code you need is:
Well, ok, thats not quite true, you also need to import ExpressionBuilder, ParserException and add a try/catch block. A complete example would look like this:
Q. Why is the cast needed?
A. The parse method will return a Filter or an Expression depending on the content of the String.
All of the following are valid epxression examples
In the above examples foo and bar are assumed to be attributes of the features that the resulting expression will be evaluated against.
Note that square brackets  and round brackets () are equivelent, though the convention is for the square brackets to denote logic precedence and for round brackets to denote arithmatic precidence.
Using a schema
The above examples will generate filters even if the named attributes do not exist leading to error messages at evaluation time. If you would rather know about the errors in advance then you can use the altertative parse method which takes a FeatureType as an extra argument.
The format of the parser is exactly the same as the format used by the toString() method in all existing filters and expressions, this means you can convert a Filter or Expression into a string, allow it to be editied and then turn it back into a filter or Expression.
The following unit test illustrates the point:
Formatted Error Messages
If the expression or filter you try to parse is malformed then a ParseException will be thrown. If you wish to present a human readable error message, complete with indication of where in the string the error occured you can use the error formater: