2013-05-11 21 views
6

Po uruchomieniu poniższego kodu otrzymuję wyjątek. Szukałem, ale nie mogłem znaleźć żadnego rozwiązania.Wyjątek w wątku "główny" 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) 

Linia numer 45 jest for (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); 

} 

} 

Odpowiedz

17

Linia

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

modyfikuje kolekcję linksList podczas iteracji nad nim. Następnym razem, poprzez pętlę for w main, Java wywołuje next w kolekcji, widzi, że kolekcja została zmodyfikowana i zgłasza wyjątek.

Podczas wykonywania ulepszonej pętli for nie można dodawać ani usuwać z kolekcji.

3

nie można nazwać add na Collection podczas zapętlenie nad nim. Tutaj:

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

zadzwonić grabLinks metody w metodzie main od wewnątrz pętli nad linksList:

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

Trzeba dodać elementy do innego Collection i skopiuj je na później.

Co miał mi zaskoczony przez chwilę było dlaczego wyjątek został pochodzący z HashMap jak przypuszczałem że linksList był List - oczywiście to Set. To nie najlepsza nazwa na świecie.

This should help.

Powiązane problemy