My idea for filtering an Enumeration or Iterator

  • Thread starter Robert Maas, see http://tinyurl.com/uh3t
  • Start date
R

Robert Maas, see http://tinyurl.com/uh3t

I'm thinking of programming a wrapper for an Enumeration or Iterator,
FilteredEnumeration or FilteredIterator respectively, which filters the
objects passing through it. Each would be a sub-class of the
corresponding API class. Each wrapper class would of course override
the two or three methods of the corresponding API class, simply calling
the API method repeatedly until the filter criterion is satisfied or
there's nothing next. These could be chained to filter on more than one
condition.


For example, you could filter according to membership in
some class per the following constructor:

FilteredEnumeration(Enumeration en, Class cl, int inheritMode,
int filterMode)

cl can be a class or an interface

inheritMode = EXACT_MATCH | ANY_SUBCLASS
filterMode = ASSERT_MATCH | DISCARD_NON_MATCH | DISCARD_MATCH
(mode ASSERT_MATCH throws an exception if object doesn't match)


For another example, you could filter on an arbitrary predicate that
takes one parameter of type Object, the predicate of course being a
Method:

FilteredEnumeration(Enumeration en, Method predicate)
static boolean predicate(Object | someClass)


predicate can be any static method of signature boolean <method>(Object)
If en is a FilteredEnumeration using ASSERT_MATCH or DISCARD_NON_MATCH
and with cl = someClass1, then predicate can be any method whose
signature is static boolean <method>(someClass2) where someClass2 is
the same class or any super-class of someClass1.


Does anybody know of such a filter already implmented and freely
available, or can I safely program it without having to worry I'm
re-inventing the wheel?

Also, I have a technical question. I'm thinking of compiling a library
of static methods which use (*) only well-known classes. If the source
code is available, then a whole bunch of such selected static methods
could be appended into one big java source file and compiled with no
problems to create a custom utility-library class suitable for small
machines where you can't afford to have the entire class that each
static method came from, or if each method costs money and you don't
need them all so don't want to pay for them all. But what if the source
isn't available? Is it possible to find a static method within a class
object, clone it, and put the clone into a custom-library class being
built, without any problems? I'm thinking that a static method is
basically unrelated to the class it's in, so it can be copied from
there and pasted anywhere else without problem, but did I overlook
something?

* (To "use" a class means to accept parameter which is instance of that
class, or use local variable or temporary value which is instance of
that class, or call static method of that class, or return object
which is instance of that class.)

So I'm thinking of a net-accessible database which indexes zillions of
different static Java methods and allows people to download any
specific method they need for their particular application.

This contrasts with instance methods and constructors, where if you
want to make any use of objects which are instances of somebody's
custom class, you probably want to download the entire class as a unit
rather than try to break it apart. So for that usage the database would
list each complete class as a single unit rather than having separate
entries for each method. (Of course it would still *document* each
public method individually so you could see if the class had what you
wanted before downloading.)

Has anybody already set up a per-single-static-method library like
that, or can I safely go ahead and implement it without "re-inventing
the wheel"?


Back to my first idea above: I'm thinking that each constructor for
different kind of filtered enumeration/iterator is really constructing
a different kind of object, so each such constructor, and the two or
three corresponding methods (hasNext, next, delete), should be in a
separate class, all of which are sub-classes of the interface
FilteredEnumeration or FilteredIterator. But an interface can't be a
sub-class of a regular class, right? So maybe I have to turn this
around backwards and instead of using a constructor I need to have a
set of static methods which are factories for constructing objects
which really are each instances of sub-classes of Enumeration or
Iterator, but all the user needs know is that the source code can
declare the variable (holding the return value from the factory) to be
of type Enumeration or Iterator and inheritance works correctly to pick
the appropriate override of hasNext/next/delete in each case. The user
of my API never need know that the actual objects are of classes named
ClassFilteredEnumeration or PredicateFilteredEnumeration etc. So
anyway, these factories for making custom objects of sub-classes of
Enumeration or Iterator, would *not* satisfy the criterion for
membership in the per-method database, because their return value is
not of a well-known type, so the user would need to download the entire
class consisting of one factory and two or three methods to be used on
the return value of the factory. But at least by using static factory
methods instead of constructors, the names can all be the same even
though each is in a different class. (There really is a
differently-named constructor for each class, but those are private
constructors, so the users never need be aware they're included in the
downloads.)

Oh, one last: The factor would be called MakeFilteredEnumeration
or MakeFilteredIterator, of course.
 
R

Ross Bamford

I'm thinking of programming a wrapper for an Enumeration or Iterator,
FilteredEnumeration or FilteredIterator respectively, which filters the
objects passing through it. Each would be a sub-class of the
corresponding API class. Each wrapper class would of course override
the two or three methods of the corresponding API class, simply calling
the API method repeatedly until the filter criterion is satisfied or
there's nothing next. These could be chained to filter on more than one
condition.

At first glance your idea would work, but I'm not sure it's really in
the spirit of Collections. Iterator and Enumeration are more lightweight
objects, such that instead of saying 'Filter all *** from this iterator'
you would instead ask the collection 'Give me an iterator over all ***'
or whatever.

The java.util.Collections class provides a number of similar classes.
Also, I have a technical question. I'm thinking of compiling a library
of static methods which use (*) only well-known classes. If the source
code is available, then a whole bunch of such selected static methods
could be appended into one big java source file and compiled with no
problems to create a custom utility-library class suitable for small
machines where you can't afford to have the entire class that each
static method came from, or if each method costs money and you don't
need them all so don't want to pay for them all. But what if the source
isn't available? Is it possible to find a static method within a class
object, clone it, and put the clone into a custom-library class being
built, without any problems? I'm thinking that a static method is
basically unrelated to the class it's in, so it can be copied from
there and pasted anywhere else without problem, but did I overlook
something?

* (To "use" a class means to accept parameter which is instance of that
class, or use local variable or temporary value which is instance of
that class, or call static method of that class, or return object
which is instance of that class.)

public static Connection getSharedConnection(); { return sharedConn; }

You would need to consider how things like this would be handled. Also,
what about methods that access the 'class' expecting a certain type of
class (perhaps newInstance'ing it)? I'm not sure it would be a workable
solution, and in any case breaking classes up to make big 'function
library' classes (.h) goes against the fundemental principals of OOP in
Java I believe.
So I'm thinking of a net-accessible database which indexes zillions of
different static Java methods and allows people to download any
specific method they need for their particular application.
?


Back to my first idea above: I'm thinking that each constructor for
different kind of filtered enumeration/iterator is really constructing
a different kind of object, so each such constructor, and the two or
three corresponding methods (hasNext, next, delete), should be in a
separate class, all of which are sub-classes of the interface
FilteredEnumeration or FilteredIterator. But an interface can't be a
sub-class of a regular class, right? So maybe I have to turn this
around backwards and instead of using a constructor I need to have a
set of static methods which are factories for constructing objects
which really are each instances of sub-classes of Enumeration or
Iterator, but all the user needs know is that the source code can
declare the variable (holding the return value from the factory) to be
of type Enumeration or Iterator and inheritance works correctly to pick
the appropriate override of hasNext/next/delete in each case. The user
of my API never need know that the actual objects are of classes named
ClassFilteredEnumeration or PredicateFilteredEnumeration etc. So
anyway, these factories for making custom objects of sub-classes of
Enumeration or Iterator, would *not* satisfy the criterion for
membership in the per-method database, because their return value is
not of a well-known type, so the user would need to download the entire
class consisting of one factory and two or three methods to be used on
the return value of the factory. But at least by using static factory
methods instead of constructors, the names can all be the same even
though each is in a different class. (There really is a
differently-named constructor for each class, but those are private
constructors, so the users never need be aware they're included in the
downloads.)

Yes, I think I see, you mean you would use a factory to return an
Iterator implemented by your new class. See java.util.Collections for
some examples of similar ideas with collections.

Cheers,
Ross
 
R

Roland

I'm thinking of programming a wrapper for an Enumeration or Iterator,
FilteredEnumeration or FilteredIterator respectively, which filters the
objects passing through it. Each would be a sub-class of the
corresponding API class. Each wrapper class would of course override
the two or three methods of the corresponding API class, simply calling
the API method repeatedly until the filter criterion is satisfied or
there's nothing next. These could be chained to filter on more than one
condition.


For example, you could filter according to membership in
some class per the following constructor:

FilteredEnumeration(Enumeration en, Class cl, int inheritMode,
int filterMode)

cl can be a class or an interface

inheritMode = EXACT_MATCH | ANY_SUBCLASS
filterMode = ASSERT_MATCH | DISCARD_NON_MATCH | DISCARD_MATCH
(mode ASSERT_MATCH throws an exception if object doesn't match)


For another example, you could filter on an arbitrary predicate that
takes one parameter of type Object, the predicate of course being a
Method:

FilteredEnumeration(Enumeration en, Method predicate)
static boolean predicate(Object | someClass)


predicate can be any static method of signature boolean <method>(Object)
If en is a FilteredEnumeration using ASSERT_MATCH or DISCARD_NON_MATCH
and with cl = someClass1, then predicate can be any method whose
signature is static boolean <method>(someClass2) where someClass2 is
the same class or any super-class of someClass1.


Does anybody know of such a filter already implmented and freely
available, or can I safely program it without having to worry I'm
re-inventing the wheel?
[snip long explanation] (sorry, I didn't read it)

There's Apache's Commons Collection library which provides a filter
iterator:
<http://jakarta.apache.org/commons/c...ons/collections/iterators/FilterIterator.html>
<http://jakarta.apache.org/commons/collections/>

An Enumeration can be adapted quite easily to an Iterator (Commons
Collection already provides such an adapter: EnumerationIterator).
--
Regards,

Roland de Ruiter
___ ___
/__/ w_/ /__/
/ \ /_/ / \
 
C

Chris Uppal

Robert said:
I'm thinking of programming a wrapper for an Enumeration or Iterator,
FilteredEnumeration or FilteredIterator respectively, which filters the
objects passing through it.

You might want to consider making wrappers for Iterables too. If you have a
FilteredIterable<E> which wraps an instance of java.lang.Iterable<E> (and which
itself implements the same interface) then you'll be able to use the new
for-loops on your wrapped object.

Is it possible to find a static method within a class
object, clone it, and put the clone into a custom-library class being
built, without any problems?

It's possible, but messier than you'd like. If the static method doesn't refer
to other static methods or static fields of the class then it's at least
logically possible. But if it does refer to other static members then you'd
have to copy the static methods too, and do something similar for static fields
(but then you'd have to find and copy the initialisation code too, unless they
fields were initialised to constants). Another problem is that the bytecode
format makes heavy use of the so-called "constants pool", and that pool is
shared between all the methods of a class. So you'd have to copy/merge the
relevant constants into your target class, /and/ find and fix-up all the
bytecodes that refer to it (which isn't necessarily easy since there are issues
to do with the wide versions of bytecodes).

All in all, it's certainly possible, and might even be quite interesting to do
(if you like that sort of thing), but it's hard to imagine it being worth the
effort. Especially since I suspect many organisations that supply bytecode
without source, will have proscriptions against copying, modifying, or
reverse-engineering their code.

-- chris
 
D

Dale King

Roland said:
I'm thinking of programming a wrapper for an Enumeration or Iterator,
FilteredEnumeration or FilteredIterator respectively, which filters the
objects passing through it. Each would be a sub-class of the
corresponding API class. Each wrapper class would of course override
the two or three methods of the corresponding API class, simply calling
the API method repeatedly until the filter criterion is satisfied or
there's nothing next. These could be chained to filter on more than one
condition.


For example, you could filter according to membership in
some class per the following constructor:

FilteredEnumeration(Enumeration en, Class cl, int inheritMode,
int filterMode)

cl can be a class or an interface

inheritMode = EXACT_MATCH | ANY_SUBCLASS
filterMode = ASSERT_MATCH | DISCARD_NON_MATCH | DISCARD_MATCH
(mode ASSERT_MATCH throws an exception if object doesn't match)


For another example, you could filter on an arbitrary predicate that
takes one parameter of type Object, the predicate of course being a
Method:

FilteredEnumeration(Enumeration en, Method predicate)
static boolean predicate(Object | someClass)


predicate can be any static method of signature boolean <method>(Object)
If en is a FilteredEnumeration using ASSERT_MATCH or DISCARD_NON_MATCH
and with cl = someClass1, then predicate can be any method whose
signature is static boolean <method>(someClass2) where someClass2 is
the same class or any super-class of someClass1.


Does anybody know of such a filter already implmented and freely
available, or can I safely program it without having to worry I'm
re-inventing the wheel?
[snip long explanation] (sorry, I didn't read it)

There's Apache's Commons Collection library which provides a filter
iterator:
<http://jakarta.apache.org/commons/c...ons/collections/iterators/FilterIterator.html>

<http://jakarta.apache.org/commons/collections/>

And another similar one that I just discovered is JGA. See this article
where it talks about this sort of thing:

http://jga.sourceforge.net/docs/AddingAlgorithms.shtml
 
R

Robert Maas, see http://tinyurl.com/uh3t

From: Roland said:
There's Apache's Commons Collection library which provides a filter
iterator:
<http://jakarta.apache.org/commons/c...ons/collections/iterators/FilterIterator.html>
Decorates an iterator such that only elements matching a predicate
filter are returned.

Unfortunately the result isn't itself an iterator, so any code calling
it as if it were an iterator would break:
boolean hasNext()
Returns true if the underlying iterator contains an object
that matches the predicate.
java.lang.Object next()
Returns the next object that matches the predicate.
So hasNext returns true even if there aren't any more items that match
the predicate, and then next throws an exception because the underlying
iterator runs off the end. I'm referring to the following standard code:
while (it.hasNext()) {
Object obj = it.next();
/* do something with obj */
}
The exception will occur whenever the very last item in the underlying
iteration fails the predicate, so after all the predicate-satisfying
items have been fetched, all of which are before that last item,
hasNext returns true because that last item hasn't yet been processed.

With a bug like that, the call to hasNext is virtually useless, so the
code basically needs to be rewritten like this:
while (true) {
Object obj;
try {
obj = it.next();
/* do something with obj */
} catch (Exception ex) {
break;
}

The right way to implement a filter iterator is to do lookahead to make
sure there really is another item in the underlying iteration that
satisfies the predicate. But then the remove method wouldn't work after
the lookahead is done. But in the standard loop the lookahead is done
only after finishing processing the old item, which might get deleted,
just before starting to look for the next item, so if the code is used
that way the lookahed for hasNext wouldn't be a problem. But still it
wouldn't be a true iterator. In summary, there is no way to write an
iterator wrapper completely correctly, but one way is not as bad as the
other, and the way jakarta did it is the worst of the two.

With an enumeration, there's no delete method, so lookahed is no
problem regardless of whether standard outer loop is done or something
less standard is done.

IMO it's stupid to use an iterator unless you really do plan to be
deleting elements as you go along. It's overkill for a task where an
enumeration would have sufficed, and given that it precludes making a
filter that works correctly it's a bad idea.

Now a filter-deleter-iterator could be made to work, or a
deleter-iterator. In addition to, or instead of, a predicate for
returns, you pass a predicate for deletion. Two modes could be:
- Return *everything* that passes the return-predicate, even if it was
deleted because it passed the delete-predicate.
- Return only items that weren't deleted.

Actually there are a whole lot of different modes possible with two
predicates, and not worth detailing here.

By the way, a reasonable alternate would be a default-value iterator or
enumeration, whereby the call to the next method contains a default
value that is returned if it runs off the end of the sequence. So then
you'd never need either a hasNext call (with lookahed and associated
problems if you're deleting anything) nor a try...catch block.
* BidiMap interface for maps that can be looked up from value to key
as well and key to value

"as well and" should read "as well as" to be correct English.

* Composite collections that make multiple collections look like one

If the same element occurs in more than one Map or Set which are
combined, how are the duplicates eliminated? Which of the copies stays
and which are like gone? If a new item is added, which of the pieces
does it go to? Has this been worked out precisely?

* Identity map that compares objects based on their identity (==)
instead of the equals method

Isn't that already trivial by supplying a comparator like that?

The WebSite says that the collections framework was added with version
1.2 of J2SE (I presume) but it doesn't say whether 1.2 is all you need
to run this new add-on or whether a more recent version is actually
needed. Do you know anyone who can say what's needed? Also, is this new
add-on free or costs money?
An Enumeration can be adapted quite easily to an Iterator (Commons

Not efficiently, because an Enumeration doesn't provide in-place delete
as you go along, so the only way to be guaranteed to implement delete
if all you have to start with is an Enumeration is to have kept a list
of everything you already enumerated and at the first delete request to
go back and delete from the very toplevel of the collection then start
a new Enumeration from the front again and if the sequence is now
grossly different from the old sequence, such as if rehashing occurred,
then you have to do a super hack checking every item to see whether
it's in the list you already did before the delete in which case you
skip it after the delete. In short, it's not worth bothering to even
try such messy and necessarily inefficient programming.

Note that it is *not* sufficient to make a list of items requested for
delete and then actually delete them only when the simulated Iterator
is finished, because the required behaviour is that the item is
*immediately* deleted from the original collection whenever requested.
Commons Collection already provides such an adapter:
EnumerationIterator

Let me look at it ... ah, I already looked at that and commented on it.
The so-called "Adapter to make Enumeration instances appear to be
Iterator instances" does *not* satisfy the semantics of an iterator, so
that introductory/title description is a lie.

I think that team has shoddy programmers who can't figure out flaws in
their logic that are obvious to me. They need to hire me to weed out
all the stuff they did that's broken and either scrap it for good if
it's impossible to do it efficient and correct or do it *right* if
possible. I'm available and have much need for earned income. If I had
my choice, I'd rather do something new and useful, such as create a
flexible interval-arithmetic package, but if there's any money for work
on fixing this broken project I'd be glad to do that.

public void setEnumeration(Enumeration enumeration)
Sets the underlying enumeration.
Parameters:
enumeration - the new underlying enumeration

No restriction on *when* you can pull that trick? So if halfway through
a simulated iteration based on an enumeration which is likewise halfway
through, if you switch the underlying enumeration to something totally
unrelated, an enumeration of a completely different collection for
example, what are the semantics? Has anybody on this team thought this
out? Or is that not allowed, you can only specify the underlying
enumeration before you call next() the first time, but nobody thought
of specifying that in the JavaDoc?

But thanks for pointing me this WebSite so I know what I did and a lot
more has already been done, so I won't waste my time without pay doing
any more of that sort of thing. The Jakarta project there will either
turn out good (if somebody sees my notes and takes a re-look at what
they did to fix the problems, or if they happen to get somebody else
equally bright to give them a kick in the butt), or crap (if they
continue their current ways, and produce something that introduces as
many new bugs as 1.1 had regarding thread-deadlocks etc. that had to be
removed in later versions, those "deprecated" methods from 1.1). In any
case it'd be a waste of time to duplicate what they've attempted.

Now if I'm mistaken, if there's nothing wrong where I pointed out
problems, please let me know! I'm always ready to learn if I
misunderstood something.
 
A

angrybaldguy

Robert said:
With an enumeration, there's no delete method, so lookahed (sic) is no
problem regardless of whether standard outer loop is done or something
less standard is done.

IMO it's stupid to use an iterator unless you really do plan to be
deleting elements as you go along. It's overkill for a task where an
enumeration would have sufficed, and given that it precludes making a
filter that works correctly it's a bad idea.

A lovely assertion, but mostly irrelevant, for two reasons:

1. Enumerations aren't available on the most common collection
interfaces in java.util (List, Set, and Map), and read-only iteration
is likely the most common use of Iterators over these collections (it
certainly is in my own code). The documentation specifically states
that Iterator takes the place of Enumeration.

Hell, the new for-loop syntax in 1.5 is a read-only way of using an
Iterator.

2. remove() is documented as being an optional operation for
iterators, so failing to support remove() doesn't violate the contract
for Iterator. While I don't like the idea of "optional" members of
interfaces (preferring subinterfaces), there is precedent for it in the
Java APIs.
 
R

Robert Maas, see http://tinyurl.com/uh3t

From: "Chris Uppal said:
You might want to consider making wrappers for Iterables too.

That's not an option at this time. I don't have access to any system
capable of running whatever version of Java has them. I have only 1.3.1
on my laptop, and the modem is not working so I have no way to download
anything newer. So I'm limited to practicing what's available on my
laptop, and with the modem broken I can't even upload the results of my
work to show anyone. The version available on my shell account on the
ISP is 1.2.2, so I'm limited to that for anything I can show anyone
online, and my access is text only so I can't show any awt/swing stuff,
only stdio and CGI.

It would take a source of seed money to provide a newer development
environment, and I don't know any source of such for my Java stuff.
Is it possible to find a static method within a class
object, clone it, and put the clone into a custom-library class being
built, without any problems?
It's possible, but messier than you'd like. If the static method
doesn't refer to other static methods or static fields of the class
then it's at least logically possible.

Yeah, what I had in mind was like the methods in the Math class which
have only two constants E and PI. I'd have to track the dependencies,
like if some trig function was implemented by multiping the argument by
I and then taking the hyperbolic function or somesuch, so I'd be sure
to include anything needed by what was asked-for. So the customer of a
high-level optional function would pay for the required low-level
utilities plus the one high-level function.
But if it does refer to other
static members then you'd have to copy the static methods too, and do
something similar for static fields (but then you'd have to find and
copy the initialisation code too, unless they fields were initialised
to constants). Another problem is that the bytecode format makes heavy
use of the so-called "constants pool", and that pool is shared between
all the methods of a class.

Hmm, slight mess, sigh.
 
R

Robert Maas, see http://tinyurl.com/uh3t

From: (e-mail address removed)
Enumerations aren't available on the most common collection
interfaces in java.util (List, Set, and Map).

That seems to be a rather moot point, considering that:
(1) Given any specific implementation of such an interface, it's rather
trivial to sub-class it to implement an enumeration for that class. So
then you declare your objects to be of that sub-class instead of the
API class.
(2) If you absolutely need a generic class that includes more than one
such sub-classed implementation class, with objects declared to be
ambiguously of the generic class instead of specifically of one of the
various implementation classes, and you absolutely need Enumeration to
be defined over that whole generic class instead of just over each
specific implementation, so that you can compile Enumeration code that
doesn't care which implementation class happens at runtime, you can
make a runtime interface as I demonstrated a few weeks ago.

Also, I prefer "weak enumerations" instead anyway. Single method
getNext or whatever which returns a default EOF value when it's reached
the end, otherwise returns the next item in the sequence, avoiding the
need to first test isNext and then somehow trust it when in fact it
sometimes lies and getNext then throws exception due to the bug.
While I don't like the idea of "optional" members of interfaces
(preferring subinterfaces), there is precedent for it in the Java APIs.

There's precedent for a whole lot of bad ideas. They should all be
deprecated rather than glorified as examples to emulate elsewhere.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top