11

We can use the old for loop (for(i = 0, j = 0; i<30; i++,j++)) with two variables Can we use the for-each loop (or the enhanced for loop) in java (for(Item item : items) with two variables? What's the syntax for that?

dogfish
  • 2,646
  • 4
  • 21
  • 37

6 Answers6

10

No you can't. It is syntactic sugar for using Iterator. Refer here for a good answer on this issue.

You need to have an object that contains both variables.

It can be shown on a Map object for example.

for (Map.Entry<String,String> e: map.entrySet()) {
    // you can use e.getKey() and e.getValue() here
}
Community
  • 1
  • 1
Tala
  • 8,888
  • 5
  • 34
  • 38
10

Unfortunately, Java supports only a rudimentary foreach loop, called the enhanced for loop. Other languages, especially FP ones like Scala, support a construct known as list comprehension (Scala calls it for comprehension) which allows nested iterations, as well as filtering of elements along the way.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
4

The following should have the same (performance) effect that you are trying to achieve:

List<Item> aItems = new List<Item>();
List<Item> bItems = new List<Item>();
...
Iterator aIterator = aItems.iterator();
Iterator bIterator = bItems.iterator();
while (aIterator.hasNext() && bIterator.hasNext()) {
    Item aItem = aIterator.next();
    Item bItem = bIterator.next();
}
ajuser
  • 179
  • 1
  • 5
1

The foreach loop assumes that there is only one collection of things. You can do something for each element per iteration. How would you want it to behave that if you could iterate over two collections at once? What if they have different lenghts?

Assuming that you have

Collection<T1> collection1;
Collection<T2> collection2;

You could write an iterable wrapper that iterates over both and returns some sort of merged result.

for(TwoThings<T1, T2> thing : new TwoCollectionWrapper(collection1, collection2) {
    // one of them could be null if collections have different length
    T1 t1 = thing.getFirst();
    T2 t2 = thing.getSecond();
}

That's the closest what I can think of but I don't see much use for that. If both collections are meant to be iterated together, it would be simpler to create a Collection<TwoThings> in the first place.

Besides iterating in parallel you could also want to iterate sequentially. There are implementations for that, e.g. Guava's Iterables.concat()

zapl
  • 63,179
  • 10
  • 123
  • 154
1

The simple answer "No" is already given. But you could implement taking two iterators as argument, and returning Pairs of the elements coming from the two iterators. Pair being a class with two fields. You'd either have to implement that yourself, or it is probably existent in some apache commons or similar lib.

This new Iterator could then be used in the foreach loop.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
0

I had to do one task where I need to collect various data from XML and store in SET interface and then output them to a CSV file.

I read the data and stored it in Set interface object as x,y,z.

For CSV file header, I used string buffer to hold the headers String buffer

StringBuffer buffer = new StringBuffer("");
buffer.append("FIRST_NAME,LAST_NAME,ADDRESS\r\n") 

Set<String> x = new HashSet<String>();
Set<String> y = new HashSet<String>();
Set<String> z = new HashSet<String>();

....

Iterator iterator1 = x.iterator()
Iterator iterator2 = y.iterator()
Iterator iterator3 = z.iterator()

while(iterator1.hasNext() && iterator2.hasNext() && iterator3.hasNext()){

    String fN = iterator1.next()
    String lN = iterator2.next()
    String aDS = iterator3.next()
    buffer.append(""+fN+","+lN+","+aDS+"\r\n")

 }
sravan
  • 1