开发者

Iteration over a list in Java

开发者 https://www.devze.com 2023-03-08 13:06 出处:网络
The problem is as follows: Write a static method subsets that uses recursive backtracking to find every possible sub-list of a given list. A sub-list of a list L contains 0 or more of L\'s elements.

The problem is as follows:

Write a static method subsets that uses recursive backtracking to find every possible sub-list of a given list. A sub-list of a list L contains 0 or more of L's elements. Your method should accept a List of strings as its parameter and print ever开发者_JS百科y sub-list that could be created from elements of that list, one per line. For example, suppose a variable called list stores the following elements:

[Janet, Robert, Morgan, Char]

The call of subsets(list); would produce output such as the following:

[Janet, Robert, Morgan, Char]
[Janet, Robert, Morgan]
[Janet, Robert, Char]
[Janet, Robert]
[Janet, Morgan, Char]
[Janet, Morgan]
[Janet, Char]
[Janet]
[Robert, Morgan, Char]
[Robert, Morgan]
[Robert, Char]
[Robert]
[Morgan, Char]
[Morgan]
[Char]
[]

Part of my solution calls for the use of recursive backtracking:

ListIterator<String> itr = choices.listIterator();
      while (itr.hasNext()) {
         String word = itr.next();
         chosen.add(word);
         itr.remove();
         subsets(choices, chosen, alreadyPrinted);
         chosen.remove(word);
         itr.add(word);
      }

But I get the ConcurrentModificationException on the line that has itr.add(word). Why? I thought the whole point of the ListIterator is to avoid that problem?

EDIT: I also tried solving it like this:

for (String word : choices) {
         List<String> choicesCopy = choices;
         chosen.add(word);
         choicesCopy.remove(word);
         subsets(choicesCopy, chosen, alreadyPrinted);
      } 

I still get a concurrentmodificationexception.... : ( How is this happening? There is no modification of the original list at all...


Not exactly, the problem is (most probably) that you create ListIterator() each time you go recursive. Each List Iterator is trying to modify the same underlying list of words, which triggers the exception. This is not allowed.

The solution is to provide a copy of the list of words each time you go recursive. Like that, each list iterator will work on its own personal list.


you create new iterator on every recursion call and then you remove/add using it. When you go up the stack, old iterator detects change and produces exception.

You should rethink this code.


EDIT: I missed that the OP was using a ListIterator.

The reason for the ConcurrentModificationException is that you are modifying the underlying list by adding and removing elements from it while you are iterating over it. I believe you will have to use a more primitive iteration technique, like the traditional for loop and keep track of the iteration value yourself.

From the above link:

if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception

Here is another quick article on it.


Your second solution has a simple mistake in it.

List<String> choicesCopy = choices;

This does not create a copy of the list. You could use ArrayList.clone() or LinkedList.clone() or create a new list like this

List<String> choicesCopy = new LinkedList<String>(choices);
0

精彩评论

暂无评论...
验证码 换一张
取 消