3
List<String> stringList;

//fill with strings somehow

Collection<String> stringCollection = (Collection<String>) stringList;

for(String str : stringCollection){
  //will this loop be guaranteed to iterate in the order found in stringList
}

I think it is guaranteed that this for-each loop will iterate in the correct order, since the syntactic sugar actually uses an iterator and the iterator() method is overridden in List to have an order. Since the run time type of stringCollection is a List, then it will use the overridden method which starts at the beginning of the list. Is this correct?

Community
  • 1
  • 1
lazarusL
  • 236
  • 3
  • 13
  • 1
    did you try it out? not that difficult to write a test case for it.. if you did try, what happened? ;) – posdef Apr 21 '15 at 14:23
  • 2
    @posdef trying it out will not answer the question if this behavior is guaranteed. – Puce Apr 21 '15 at 14:24

4 Answers4

2

Yes, the enhanced for loop will use the iterator of the provided collection. So if b is really a list (runtime type), then the order will be guaranteed.

Note that with the new stream API (Java SE 8) this is a little bit different.

While b.stream() would still guarantee the order, b.parallelStream() wouldn't.

Also see: https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#ordering

Puce
  • 37,247
  • 13
  • 80
  • 152
2

http://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#iterator()

Returns an iterator over the elements in this collection. There are no guarantees concerning the order in which the elements are returned (unless this collection is an instance of some class that provides a guarantee).

Puce
  • 37,247
  • 13
  • 80
  • 152
Marek-A-
  • 474
  • 12
  • 29
1

Yes.

Collection.iterator is implemented by the JDK implementations of Collection, like ArrayList. This is inherent to how object oriented programming works; if you call a method of an object where you only know one of it's interfaces, it will still call the method of the fully implemented class.

Community
  • 1
  • 1
durron597
  • 31,968
  • 17
  • 99
  • 158
0

Neither the Collection nor List interface provide an implementation for the iterate() method, so this implementation must come from the run-time type of the object you're iterating over. So yes, the collection will iterate in a predictable order if you use an ordered list.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • It would come from the run-time type of the object even if one of Collection and List were abstract classes and did provide an implementation for the `iterator()` method. – durron597 Apr 21 '15 at 14:31
  • @durron597 So? They're not abstract classes, so that's irrelevant. – Bill the Lizard Apr 21 '15 at 14:33
  • Yes, but the implementation always comes from the run-time type. You said "implementation comes from the run-time type **because** the interfaces don't provide an implementation", but actually implementation comes from the run-time type **no matter what**. – durron597 Apr 21 '15 at 14:35
  • 1
    @durron597 And in this case they are interfaces, so there's nowhere else for the implementation to even come from, which was my point. Don't use quotes when you're paraphrasing. – Bill the Lizard Apr 21 '15 at 14:38
  • @BilltheLizard Since Java SE 8, interface can specify default implementations, but neither Collection nor List nor Iterable does in the case of the iterator-method. – Puce Apr 21 '15 at 14:53