Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2006

Tip: Looking for answers? Try searching our database.

for each and non-java.util.* collections

Thread view: 
Aryeh M. Friedman - 23 Apr 2006 19:13 GMT
If I have the following class:

import java.util.Iterator;

// the simplest possible collection that does something useful with all
the Iterator mandated
// methods
public class MyCollection<T> implements Iterable, Iterator
{
   private T[] arr;
   private int pos;

   public MyCollection()
   {
       arr=(T[]) arr;
       pos=0;
   }

   public Iterator<T> iterator()
   {
       return this;
   }

   public boolean hasNext()
   {
       return pos!=arr.length;
   }

   public T next()
   {
       return arr[pos++];
   }

   public void remove()
   {
       T[] tmp=(T[]) new Object[arr.length-1];
       int i=0;

       for(i=0;i<pos-1;i++)
           tmp[i]=arr[i];

       for(i=pos;i<arr.length;i++)
           tmp[i]=arr[i];

       arr=tmp;
   }
}

and I write a test class for it:

public class MyCollectionTest
{
   public static void main(String[] args)
   {
       MyCollection<Integer> c=new MyCollection<Integer>();

       for(Object i:c)
           System.out.println(i);
   }
}

stuff works fine (except for the obvious need to case i if I was going
to use it as a T)... now if I do for(Integer i:c) I get:

Incompatible types: java.lang.Object but expected java.lang.Integer

Am I missing something about generics, iterators and/or foreach?
Thomas Hawtin - 23 Apr 2006 18:47 GMT
> public class MyCollection<T> implements Iterable, Iterator

public class MyCollection<T> implements Iterable<T>, Iterator<T>

But I strongly suggest it does not implement Iterator itself.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Hendrik Maryns - 24 Apr 2006 11:07 GMT
Thomas Hawtin schreef:
>> public class MyCollection<T> implements Iterable, Iterator
>
> public class MyCollection<T> implements Iterable<T>, Iterator<T>
>
> But I strongly suggest it does not implement Iterator itself.

Why?  I’ve done this before too, and don’t see a problem in it.

I.e. public Iterator iterator { return this; }

H.
- --
Hendrik Maryns

==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Chris Uppal - 24 Apr 2006 12:22 GMT
> > But I strongly suggest it does not implement Iterator itself.
>
> Why?  I've done this before too, and don't see a problem in it.
>
> I.e. public Iterator iterator { return this; }

How do you handle two simulataneous iterations ?  Or are your objects (when
viewed as Iterators) stateless ?  I can't see how that can work.

Anyway, an iterator and the collection it iterates over, are two completely
different things.  I don't see any advantage, and /considerable/ scope for
confusion, in conflating the two.

   -- chris
Hendrik Maryns - 24 Apr 2006 12:53 GMT
Chris Uppal schreef:

>>> But I strongly suggest it does not implement Iterator itself.
>> Why?  I've done this before too, and don't see a problem in it.
[quoted text clipped - 3 lines]
> How do you handle two simulataneous iterations ?  Or are your objects (when
> viewed as Iterators) stateless ?  I can't see how that can work.

Good point.  I’ll have to have a look at it, and probably change it
indeed.  The reason was, that I have some classes computing
combinatorics, and their main use is to iterate over all possible
combinations/variations/permutations/... of the array that is given to
them.  So actually, they are iterators.  Now it is very convenient to
make them implement Iterable, in order to be able to do this:

Integer[] integerArray;
// initialise array
for (Integer[] indices : new Combinator<Integer>(integerArray, 5) ){
    // indices goes through all combinations of 5 out of the integer
    // array
}

Unfortunately, this is not possible if Combinator only implements
Iterator.  And I think it’s a bit convoluted to create an extra wrapper
class implementing Iterable and returning a Combinator.  But indeed
simultaneous iterations is asking for problems.  I suppose I’ll just put
that in the doc, though.

> Anyway, an iterator and the collection it iterates over, are two completely
> different things.  I don't see any advantage, and /considerable/ scope for
> confusion, in conflating the two.

I agree with you point, that you should not mix a collection and its
iterator.  However, you seem to forget that iterators not necessarily
are bound to some collection.  As my example above, an iterator can
iterate through other things, too.  (Ok, in the end, that is a
collection too, but one that does never actually exist: there is no
point in actually creating all elements of the collection, as they are
fully predictable.)

H.
- --
Hendrik Maryns

==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Chris Uppal - 24 Apr 2006 16:31 GMT
> Good point.  I'll have to have a look at it, and probably change it
> indeed.  The reason was, that I have some classes computing
[quoted text clipped - 12 lines]
> Unfortunately, this is not possible if Combinator only implements
> Iterator.

I think you are thinking of it the wrong way around.  The Combinator is (or
would be if you did this /my/ way ;-) a factory for iterators.  The iterators
themselves have no independent existence (there's no real need for a public
class, for instance).  So your code snippet remains unchanged, but most of the
iteration logic moves out of Combinator<T>, and into an inner class which
implements Iterable<T>.

BTW, if you do that you can, if you choose, make your Iterator iterate over
permutations of a List (or array) which is held in the Combinator (rather than
only over /indexes/ into that List).  I don't know whether you would prefer
that way of doing things, but that's the way I've chosen to do it in my own
code.

> However, you seem to forget that iterators not necessarily
> are bound to some collection.  As my example above, an iterator can
> iterate through other things, too.

I agree, I was using the language rather loosely.  Or rather, ambiguously --
the word collection certainly includes "virtual collections" (such as the set
of all permutations of <something>), but it can also be taken to refer to
Java's Collections which are all concrete containers (rather than general
collections) and -- as such -- misnamed.

   -- chris
Hendrik Maryns - 25 Apr 2006 09:38 GMT
Chris Uppal schreef:

>> Good point.  I'll have to have a look at it, and probably change it
>> indeed.  The reason was, that I have some classes computing
[quoted text clipped - 19 lines]
> iteration logic moves out of Combinator<T>, and into an inner class which
> implements Iterable<T>.

I commit this sounds better than what I have now.  That will be the
umpteenth TODO in the Task list...

> BTW, if you do that you can, if you choose, make your Iterator iterate over
> permutations of a List (or array) which is held in the Combinator (rather than
> only over /indexes/ into that List).  I don't know whether you would prefer
> that way of doing things, but that's the way I've chosen to do it in my own
> code.

It does already.  The example was not well-chosen, but you could replace
Integer with any class in the above example.  You can see the code on
http://mindprod.com/jgloss/combination.html.

H.
- --
Hendrik Maryns

==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Hendrik Maryns - 25 Apr 2006 09:47 GMT
Hendrik Maryns schreef:
> Chris Uppal schreef:
>>> Hendrik Maryns wrote:
[quoted text clipped - 24 lines]
> I commit this sounds better than what I have now.  That will be the
> umpteenth TODO in the Task list...

OTOH, the classes aren’t meant to persist anyway, so just as easy to
create a new Combinator(someArrayIalreadyHave) as first assigning a
combinator to a variable and asking for its iterator method (or indeed
using it in foreach).

They are only utility classes, so I don’t know whether it is very useful
to create yet another iterator class just for the benefit of being this
little more robust.  Hm, I don’t like what I am writing here, maybe it
is.  I mean, doing one iteration would involve creating two classes
then, neither of which will probably be reused.

H.
- --
Hendrik Maryns

==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Chris Uppal - 26 Apr 2006 10:30 GMT
> Hm, I don't like what I am writing here, [...]

;-)

Come now, Hendrik, you know you aren't going to be happy until you've changed
the implementation...

   -- chris
Stefan Ram - 24 Apr 2006 14:38 GMT
>How do you handle two simulataneous iterations ?

 Do you mean nested iterations?
 (Another interpretation could be iterations in two threads.)

 A type implementing both »Iterator« and »Iterable« as if by

public java.util.Iterator iterator(){ return this; }

 is called an »iteration« by me.

 An example for nested iterations:

public class Main
{ public static void main( final java.lang.String[] args )
 {
   for( java.lang.Integer i : new
     de.dclj.ram.system.iteration.IntegralRange( 10, 12 ))
   java.lang.System.out.println( i );

   for( de.dclj.ram.type.tuple.Tuple i :
     new de.dclj.ram.system.iteration.TupleNesting
     <java.lang.Integer,java.lang.Integer>
     ( new de.dclj.ram.system.iteration.IntegralRange( 1, 3 ),
       new de.dclj.ram.system.iteration.IntegralRange( 2, 5 )))
   java.lang.System.out.println( i ); }}

 This prints:

10
11
12
( 1; 2 )
( 1; 3 )
( 1; 4 )
( 1; 5 )
( 2; 2 )
( 2; 3 )
( 2; 4 )
( 2; 5 )
( 3; 2 )
( 3; 3 )
( 3; 4 )
( 3; 5 )

 The first loop is an example of a simple iteration.

 The second shows an iteration combinator combining two
 iterations into a new nested iteration. (I believe, you asked
 whether this is possible.)

 I also could have used two nested for-loops. The above code
 only was written with the intention to also demonstrate
 »TupleNesting«

                         ~~~

 The source code for the types used should be
 browsable as part of my ram.jar publication:

http://www.purl.org/stefan_ram/pub/ram-jar

 (The »distribution« on this page is an older version, possibly
 not containing the types used here. But the link »Online
 API-specification with links to online-source code« should
 lead to the source code. This is a preliminary and incomplete
 pre-alpha publication of my library only. I am in the process
 of preparing an alpha release.)

                         ~~~

 Another example: How to get the comma separated segments
 from the file »tmp.txt«?

1,2,3
alpha, beta, 3

 Answer: Combine a line iteration with a segment iteration:

public class Main
{ public static void main( final java.lang.String[] args )  
 { de.dclj.ram.java.io.LineReadableAndClosable reader = new
   de.dclj.ram.java.io.DefaultLineReadableAndClosable
   ( new java.io.BufferedReader
     ( new de.dclj.ram.java.io.FileReader
       ( new de.dclj.ram.java.io.DefaultPath( "tmp.txt" )).getFileReader() ));
   for( java.lang.String i :
     new de.dclj.ram.system.iteration.DependentNesting
     <java.lang.String,java.lang.String>
     ( new de.dclj.ram.java.io.Lines( reader ),
       de.dclj.ram.java.lang.StringSegments.class ))
   java.lang.System.out.println( i ); }}

 This prints:

1
2
3
alpha
beta
3

 (StringSegments objects always use the comma "," as a
 separator, customizing them to use another seperator might be
 possible in a later version.)
Chris Uppal - 25 Apr 2006 10:01 GMT
[me:]
> > How do you handle two simulataneous iterations ?
>
>   Do you mean nested iterations?

No (though I like the idea and may even "borrow" it ;-).  All I was talking
about was the case where you have two iterators active on the same collection
(in the wide sense) at the same time.

E.g if you have a method which does a pairwise scan over two collections:

boolean
check(Iterable<Something> a, Iterable<Something> b)
{
   Iterator<Something> overA = a.iterator();
   Iterator<Something> overB = b.iterator();

   while (overA.hasNext() && overB.hasNext())
       if (someRelationshipBetween(a.next(), b.next())
           return true;

   return false;
}

There is no reason why it should not be called with a == b, but Hendrik's
current implementation (unecessarily, as it turns out) does not allow that.

   -- chris
Aki Tuomi - 23 Apr 2006 19:49 GMT
Aryeh M. Friedman kirjoitti:
> If I have the following class:
>
[quoted text clipped - 63 lines]
>
> Am I missing something about generics, iterators and/or foreach?

for(Integer i: c) {
..
}


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.