Iteration over a list in Java

☆樱花仙子☆ 提交于 2019-12-11 04:47:16

问题


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 every 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...


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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);


来源:https://stackoverflow.com/questions/6146690/iteration-over-a-list-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!