Range Over Channels in Karel
In a previous example we saw how for
and foreach
provide iteration over basic data structures. We can also use similar syntax to iterate over values received from a queue.
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class RangeOverQueue {
public static void main(String[] args) throws InterruptedException {
// We'll iterate over 2 values in the queue.
BlockingQueue<String> queue = new LinkedBlockingQueue<>(2);
queue.put("one");
queue.put("two");
// This loop iterates over each element as it's
// received from queue. Because we don't add any
// more elements after the initial two, the iteration
// terminates after receiving the 2 elements.
while (!queue.isEmpty()) {
String elem = queue.take();
System.out.println(elem);
}
}
}
When you run this program, you’ll see:
$ java RangeOverQueue
one
two
This example also showed that it’s possible to iterate over a non-empty queue until it’s empty. In Java, we use a BlockingQueue
which is similar to a channel in other languages, allowing for concurrent access and blocking operations.
Note that Java doesn’t have a direct equivalent to Go’s range
over channels. Instead, we use a while
loop and the take()
method of BlockingQueue
, which blocks until an element is available. This achieves a similar effect of processing elements as they become available in the queue.