In a game I have a list of players, let's say like this:
LinkedList<String> players = new LinkedList<String>();
I want to let each player interact with each of the other players, so I write two nested loops:
Iterator<String> i1 = players.iterator();
while (i1.hasNext()) {
String p1 = i1.next();
Iterator<String> i2 = players.iterator();
// But I want to do this: Iterator<String> i2 = i1.clone();
while (i2.hasNext()) {
String p2 = i2.next();
System.out.println("Interact: " + p1 + ", " + p2);
}
}
Since I only want each pair of players to interact once, I want to start the inner loop with the player after the outer loop's current player. So I want to clone the iterator, but that doesn't compile.
So, what should I do instead?
Iterator takes the place of Enumeration in the Java Collections Framework. Iterators differ from enumerations in two ways: Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics. Method names have been improved.
The hasNext() method of ListIterator interface is used to return true if the given list iterator contains more number of element during traversing the given list in the forward direction.
To clone a list, one can iterate through the original list and use the clone method to copy all the list elements and use the add method to append them to the list. Approach: Create a cloneable class, which has the clone method overridden. Create a list of the class objects from an array using the asList method.
The following will do it:
ListIterator<String> i1 = players.listIterator(0);
while (i1.hasNext()) {
String p1 = i1.next();
ListIterator<String> i2 = players.listIterator(i1.nextIndex());
while (i2.hasNext()) {
String p2 = i2.next();
System.out.println("Interact: " + p1 + ", " + p2);
}
}
It relies on the ListIterator
's ability to start from the given position and to also know its current position.
In addition to aix answer, I'd like to point out that however you create an iterator starting at a specific index, it's bound to be a linear operation. If it wasn't, you would be able to do arbitrary access to the list in constant time using
elementN = createIterator(linkedList, N).next();
which would be contradictory.
In your situation I therefore believe that the most efficient solution would actually be to do
List<String> tmp = new ArrayList<String>(players);
for (int p1 = 0; p1 < tmp.size(); p1++)
for (int p2 = p1+1; p2 < tmp.size(); p2++)
System.out.println("Interact: " + tmp.get(p1) + ", " + tmp.get(p2));
Note however, that it is still the same complexity as the solution by aix; O(n2) but probably with a smaller constant factor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With