How to Most Elegantly Iterate Through Parallel Collections

How to most elegantly iterate through parallel collections?

I would create a new object that encapsulates the two. Throw that in the array and iterate over that.

List<Person>

Where

public class Person {
public string name;
public int age;
}

How to most elegantly iterate through parallel collections in C#?

This is known as "zipping" or "zip joining" two sequences. Eric Lippert describes this very algorithm and provides an implementation.

Parallel iteration on multiple collections

I don't think he meant "in parallel" as in concurrently.

It is much simpler. Suppose you have two Collections and you want the same loop (not a nested loop) to iterate over both of them, taking the i'th element of each one in each iteration. You can't do that with the enhanced for loop, since it hides the indices and the iterator.

You must use the standard for loop (for ordered Collections) :

private List<String> one;
private List<String> two;

public void run(){
for(int i = 0; i<one.size() && i<two.size();i++){
// do something with one.get(i) and two.get(i)
}
}

Or explicit Iterators (for un-ordered Collections) :

private Set<String> one;
private Set<String> two;

public void run(){
for(Iterator<String> iterOne=one.iterator(),Iterator<String> iterTwo=two.iterator(); iterOne.hasNext()&&iterTwo.hasNext();){
// do something with iterOne.next() and iterTwo.next()
}
}

How to Iterate through two ArrayLists Simultaneously?

You can use Collection#iterator:

Iterator<JRadioButton> it1 = category.iterator();
Iterator<Integer> it2 = cats_ids.iterator();

while (it1.hasNext() && it2.hasNext()) {
...
}

How do I iterate over multiple lists in parallel in Java?

A compound Iterator might be a cool idea, e.g.:

Iterator<Array<?>> compoundIterator = createIterator(List1, List2, List3);

Then inside the implementation, you would create iterators for each of the lists, then loop through the items and put them into an array, then your consumption of that stuff would look something like:

while (compoundIterator.hasElements()){
Array[] elements = compountIterator.nextElement();
calculate(elements[0], elements[1], elements[2]);
}

What's nice about this solution is you are hiding all those details about whether one list ran out or not (of course you have to decide what you want to do if one does, but that could be wrapped inside as well).

How to iterate over two Collections of Objects simultaneously?

Something like this:

public static boolean compareCollection(Collection<Object> c1, Collection<Object> c2)   {
if (c1 == null)
return c2 == null;
else if (c2 == null || c1.size() != c2.size())
return false;
Iterator<Object> it1 = c1.iterator();
Iterator<Object> it2 = c2.iterator();
while (it1.hasNext()) {
Object o1 = it1.next();
Object o2 = it2.next();
if (!o1.equals(o2))
return false;
}
return true;
}

Of course, you'll have to parameterize the collections with the right type (which I'm guessing is not just Object) and making the appropriate comparison:

if (!o1.val.equals(o2.val))

Nifty way to iterate over parallel arrays in Java using foreach

I would use a Map myself. But taking you at your word that a pair of arrays makes sense in your case, how about a utility method that takes your two arrays and returns an Iterable wrapper?

Conceptually:

for (Pair<K,V> p : wrap(list1, list2)) {
doStuff(p.getKey());
doStuff(p.getValue());
}

The Iterable<Pair<K,V>> wrapper would hide the bounds checking.

How do I efficiently iterate over each entry in a Java Map?

Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}

On Java 10+:

for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}

Java: Best/elegant way to iterate over 2 lists

public interface Processor<T> {
public void process(T object);
}

And then a helper method:

public static <T> void processAll(Collection<T> items, Collection<? extends Processor<T>> processors) {
Iterator<T> i = items.iterator();
Iterator<? extends Processor<T>> p = processors.iterator();
while(i.hasNext() && p.hasNext())
p.next().process(i.next());
}

You could put that helper method on the class which uses it, if there is only one (and make it private), or put it a utility class which is shared by the entire program.

Of course there are other ways to code processAll; for example, you could use a for loop on one of the collections. But in any case, breaking this low-level code out into a helper method will make your higher-level code cleaner and less "noisy". And if you are doing something similar in multiple parts of the program, they can share the helper method.

Java 8: Parallel FOR loop

Read up on streams, they're all the new rage.

Pay especially close attention to the bit about parallelism:

"Processing elements with an explicit for-loop is inherently serial. Streams facilitate parallel execution by reframing the computation as a pipeline of aggregate operations, rather than as imperative operations on each individual element. All streams operations can execute either in serial or in parallel."

So to recap, there are no parallel for-loops, they're inherently serial. Streams however can do the job. Take a look at the following code:

    Set<Server> servers = getServers();
Map<String, String> serverData = new ConcurrentHashMap<>();

servers.parallelStream().forEach((server) -> {
serverData.put(server.getIdentifier(), server.fetchData());
});


Related Topics



Leave a reply



Submit