Make iterators cloneable?
Remi Forax
forax at univ-mlv.fr
Sun Sep 11 09:40:52 UTC 2016
Hi,
digging a little bit in the bug database, there is a bug from 1999
https://bugs.openjdk.java.net/browse/JDK-4244952
answers seems to be
- having different iterators on the same collection is error prone because iterators are failfast,
the proposed workaround to use an array or a List with several indexes
- it's too C++ish, C++ defines clone and equals, Java tries to define a simpler iteration protocol
(from now, given that this question is raised only once in a while, it's doesn't seem to be a bad idea)
- iterators are interfaces, so having several iterators means several virtual dispatch calls
(this one is not true anymore because any JITs routinely devirtualize this kind of call).
cheers,
Rémi
----- Mail original -----
> De: "Dave Brosius" <dbrosius at mebigfatguy.com>
> À: "Louis Wasserman" <lowasser at google.com>, "Jonathan Bluett-Duncan" <jbluettduncan at gmail.com>
> Cc: core-libs-dev at openjdk.java.net
> Envoyé: Dimanche 11 Septembre 2016 02:23:41
> Objet: Re: Make iterators cloneable?
>>> Iterators reading from a BufferedReader
>
> yes that's true. altho given the contract of Cloneable, adding the clone
> method on Iterator would be safe, as it would only be available if the
> real implementing class 'extends Cloneable'... it's actually kind of
> funny that Object methods aren't available on interface references, anyway.
>
>
> But i get the "age of Iterator" answer.. Shame there isn't an answer, tho.
>
> thanks, dave
>
> On 09/10/2016 07:44 PM, Louis Wasserman wrote:
>> Some iterators might be. Many may not be. Certainly Iterator as an
>> interface has been out there for long enough there are Iterator
>> implementations out there that aren't cloneable -- say, Iterators
>> reading from a BufferedReader, where there really won't be any way to
>> do what you're hoping for; BufferedReaders certainly aren't cloneable.
>>
>> On Sat, Sep 10, 2016 at 4:33 PM Dave Brosius <dbrosius at mebigfatguy.com
>> <mailto:dbrosius at mebigfatguy.com>> wrote:
>>
>> Yes Louis is correct.
>>
>> I want the pair wise associations or all elements of a set.
>>
>> Fee-Fi
>>
>> Fee-Fo
>>
>> Fee-Fum
>>
>> Fi-Fo
>>
>> Fi-Fum
>>
>> Fo-Fum
>>
>>
>> the independent iterators produce Fee-Fee (etc) as well as the
>> duplicate Fee-Fi and Fi-Fee (etc), both of which i don't want.
>>
>>
>> This is obviously simplistic with index based collections, but not
>> with sets/maps
>>
>> I don't see why an Iterator isn't by nature easily cloneable.
>>
>>
>>
>> On 09/10/2016 06:45 PM, Jonathan Bluett-Duncan wrote:
>>> Ah okay Louis, if that's the case then that certainly makes
>>> sense, and I'd agree that there's no good way of doing so, as one
>>> would need to copy the set into a list.
>>>
>>> Dave, did Louis hit the mark? If not, would you kindly go into
>>> further detail as to exactly what it is you're trying to do?
>>>
>>> Best,
>>> Jonathan
>>>
>>> On 10 September 2016 at 23:36, Jonathan Bluett-Duncan
>>> <jbluettduncan at gmail.com <mailto:jbluettduncan at gmail.com>> wrote:
>>>
>>> Hi Dave,
>>>
>>> Rather than using Iterator.clone(), how about you just call
>>> collection.iterator() 2 times to return 2 unique, non-same
>>> iterators; something like the following:
>>>
>>> import java.util.Collections;
>>> import java.util.Iterator;
>>> import java.util.Set;
>>> import java.util.concurrent.ConcurrentHashMap;
>>>
>>> public class Example {public static void main(String[] args) { Set<String> s =
>>> Collections.newSetFromMap(new ConcurrentHashMap<String,
>>> Boolean>()); s.add("Fee"); s.add("Fi"); s.add("Fo");
>>> s.add("Fum"); Iterator<String> it1 = s.iterator(); for (String v1 =null;
>>> it1.hasNext(); v1 =it1.next()) {
>>> Iterator<String> it2 = s.iterator();// a completely separate iterator to it1 for
>>> (String v2 =null; it2.hasNext(); v2 = it2.next()) {System.out.println(v1 + "
>>> <-->" + v2); } } } }
>>>
>>> Or, even better, if you're using Java 5+, you can skip using
>>> Iterators altogether and use for-loops directly:
>>>
>>> import java.util.Collections;
>>> import java.util.Set;
>>> import java.util.concurrent.ConcurrentHashMap;
>>>
>>> public class Example {public static void main(String[] args) { Set<String> s =
>>> Collections.newSetFromMap(new ConcurrentHashMap<String,
>>> Boolean>()); s.add("Fee"); s.add("Fi"); s.add("Fo");
>>> s.add("Fum"); for (String v1 : s) {
>>> for (String v2 : s) {System.out.println(v1 + "<-->" + v2); } } } }
>>>
>>> Kind regards,
>>> Jonathan
>>> On 10 September 2016 at 23:13, Dave Brosius
>>> <dbrosius at mebigfatguy.com <mailto:dbrosius at mebigfatguy.com>>
>>> wrote:
>>>
>>> It would be nice to be able to associate each element in
>>> a collection with another element in the collection,
>>> which is something very easily done with index based
>>> collections, but with sets, etc this isn't so easy...
>>> unless i'm having a brainfart. So i'd like to do this,
>>> but Iterator doesn't implement Cloneable... Any reason
>>> not to? or is there another way that's missing me? public
>>> class ItClone { public static void main(String[]
>>> args) { Set<String> s =
>>> Collections.newSetFromMap(new ConcurrentHashMap<String,
>>> Boolean>()); s.add("Fee"); s.add("Fi");
>>> s.add("Fo"); s.add("Fum");
>>> Iterator<String> it1 = s.iterator(); while
>>> (it1.hasNext()) { String v1 = it1.next();
>>> Iterator<String> it2 = (Iterator<String>)
>>> it1.*clone*(); while (it2.hasNext()) {
>>> String v2 = it2.next();
>>> System.out.println(v1 + " <-->" + v2); }
>>> } } }
More information about the core-libs-dev
mailing list