2017-05-28 11 views
0

Im Versuch, in eine Liste zu sammeln alle Standorte von meinem db, die die gleichen Namen zu tun, um haben, dass Im dies mit:Wie kann ich Standorte nach Namen in meiner Datenbank filtern?

public static List<Location> searchRepe(List<Location>ls){ 
     List<Location>res=new ArrayList<Location>(); 
     for(Location l:ls){ 
      ls.remove(l); 
if(ls.stream().anyMatch(x>x.getProvinceName().equals(l.getProvinceName()))){ 
       res.add(l);} 
      ls.add(l);  
     } 
     return res; 
    } 

ERROR: Exception in thread „main“ java.util.ConcurrentModificationException

Ich entferne zuerst den Standort der Liste und überprüfe dann, ob es einen anderen Ort mit demselben Namen gibt. Nachdem ich überprüft habe, ob der Name des Ortes in der Liste ist, füge ich ihn meiner Res List hinzu. In jedem Fall werde ich immer die ursprüngliche Liste behalten, weil ich nach der Überprüfung das Element in der Liste gelesen habe. Ich weiß, dass der Fehler verursacht wird, weil ich jede Iteration entferne und hinzufüge, aber wenn ich in jeder Iteration entferne und dann dasselbe Element hinzufüge, wird die Größe der Liste immer gleich sein.

Könnte mir jemand einen besseren Weg sagen, dies zu tun? Wenn es möglich ist java8 mit

Antwort

0

Die foreach Anweisung Iterator verwendet Element abzurufen, und Iterator kann nicht Gegenstand entfernen direkt, sonst wird das Verfahren ConcurrentModificationException werfen. So können Sie Artikel aus der Liste durch folgenden Ansatz entfernen:

for (int index = 0; index < list.size(); index++) { 
    if(condition){ 
     list.remove(index); 
     index--; 
    } 
} 

In Ihrem Problem, können Sie Multimap verwenden, das ist eine neue Kollektion Art in Guava Bibliothek, wie folgt aus:

public static List<Location> searchRepe(List<Location>ls){ 
    Multimap<String,Location> locationMap = HashMultimap.create(); 
    for (Location l : ls) { 
     locationMap.put(l.getProvinceName(),l); 
    } 
    List<Location> result=new ArrayList<>(); 
    for (Map.Entry<String, Collection<Location>> entry : locationMap.asMap().entrySet()) { 
     Collection<Location> value = entry.getValue(); 
     if(value.size()>1){ 
      Location next = value.iterator().next(); 
      result.add(next); 
     } 
    } 
    return result; 
} 

Achten Sie auf diese Linie locationMap.put(l.getProvinceName(),l), das Ergebnis der put Methode hängt von der equals Methode in Location Klasse.

0

Wenn Sie unbedingt Stream und Java8 verwenden möchten, glaube ich, dass dies die richtige Lösung ist. filtern Sie einfach alle Elemente, bei denen Anzahl der Vorkommen basieren auf ProvinceName mehr als ein

public static List<Location> searchRepe(List<Location> ls) { 

    return ls.stream() 
      .filter(
        location -> ls.stream() 
            .map(Location::getProvinceName) 
            .filter(n -> Objects.equals(n, location.getProvinceName())) 
            .count() > 1L 
      ) 
      .collect(Collectors.toList()); 
} 

oder durch Gruppierung von

public static List<Location> searchRepe(List<Location> ls) { 

    return ls.stream() 
      .collect(Collectors.groupingBy(Location::getProvinceName)) 
      .entrySet() 
      .stream() 
      .map(Map.Entry::getValue) 
      .filter(entry -> entry.size() > 1) 
      .map(entry -> entry.get(1)) 
      .collect(toList()); 
} 
+0

Die erste Methode funktioniert super vorausgesetzt, dass ich eine Liste mit allen Standorten wollten, haben ihr Provinzname gemeinsam. Bei der zweiten Methode werden nur die Standorte gesammelt, die gemäß ihrem provinceName mehr als einmal angezeigt werden. Vielen Dank Neonailol –

Verwandte Themen