2013-05-11 15 views
6

Quando si esegue il codice riportato di seguito, ottengo un'eccezione. Ho cercato ma non ho trovato nessuna soluzione.Eccezione nel thread "main" java.util.ConcurrentModificationException

Exception in thread "main" java.util.ConcurrentModificationException 
    at java.util.HashMap$HashIterator.nextEntry(Unknown Source) 
    at java.util.HashMap$KeyIterator.next(Unknown Source) 
    at com.aybits.software.linkgrabber.Grabber.main(Grabber.java:45) 

Numero di linea 45 è per (String linkFromCollection: linksList) {

public class Grabber { 

static String url; 
Document doc; 
static Set<String> linksList = new HashSet<String>(); 
String matchingString ="java2s.com/Code"; 
static boolean isCrawling = true; 
static int STOP_WATCH = 0; 

public Grabber(String url){ 
    Grabber.url = url; 
} 

public void grabLinks(String urlToCrawl) throws IOException{ 
    doc = Jsoup.connect(urlToCrawl).timeout(20 * 1000).get(); 
    Elements links = doc.select("a[href]"); 

    for (Element link : links) { 
     //print(" * a: <%s> (%s)", link.attr("abs:href"), trim(link.text(), 35)); 
     if(link.attr("abs:href").toString().contains(matchingString)){ 
      if(!linksList.contains(link.attr("abs:href").toString())){ 
       System.out.println("Added - " + link.attr("abs:href")); 
       linksList.add(link.attr("abs:href").toString()); 
      } 
     } 
    } 
} 

public static void main(String[] args) throws IOException { 
    Grabber app = new Grabber("http://java2s.com"); 
    app.grabLinks(url); 

    while(isCrawling){ 
     for(String linkFromCollection : linksList){ 
      app.grabLinks(linkFromCollection); 

      if(linksList.contains(linkFromCollection)){ 
       STOP_WATCH += 5; 
       System.out.println("STOP_WATCH IS " + STOP_WATCH); 
      }else{ 
       STOP_WATCH -= 1; 
       System.out.println("STOP_WATCH IS " + STOP_WATCH); 
      } 

      if(STOP_WATCH >= 100){ 
       isCrawling = false; 
       System.out.println("STOP_WATCH IS " + STOP_WATCH); 
      } 
     } 


    } 
    ICVSWrite writer = new ICVSWrite(); 

    String[] strArray = (String[]) linksList.toArray(); 
    writer.write(strArray); 

} 

} 

risposta

17

La linea

linksList.add(link.attr("abs:href").toString()); 

modifica la raccolta linksList mentre si sta iterando su di esso. La volta successiva attraverso il ciclo for in main, Java chiama next sulla raccolta, rileva che la raccolta è stata modificata e genera l'eccezione.

Quando si esegue un ciclo for avanzato, non è possibile aggiungere o rimuovere dalla raccolta.

3

Non è possibile chiamare add su un Collection mentre loop su di esso. Qui:

for (Element link : links) {   
    if(...){ 
     if(...){ 
      ... 
      linksList.add(link.attr("abs:href").toString()); 
         ^^^ <- here 
     } 
    } 
} 

si chiama grabLinks metodo dal tuo metodo main all'interno di un ciclo su linksList:

for(String linkFromCollection : linksList) { 
    app.grabLinks(linkFromCollection);  

È necessario aggiungere i tuoi articoli ad un altro Collection e poi copiare dopo.

cosa mi aveva perplesso per un po 'di tempo è stato il motivo per cui l'eccezione veniva da un HashMap come avevo supposto che linksList era un List - ovviamente E' un Set. Non è il miglior nome al mondo.

This should help.

Problemi correlati