2016-12-13 4 views
2

Ich habe eine Datei, die Daten in Form von JSON-Format enthält. Ich lese es Zeile für Zeile und jede Zeile hat 1 JSON-Eintrag, so dass das Format wirklich kein Problem ist. Im Folgenden finden Sie eine Beispielzeile:Java 8 Streams Zählen Sie alle Keys

{"url": "http://ldrlongdistancerider.com/bikers_rights_motorcycle/rightsriders0163.php", "timestamp": 1257072412, "tags": ["nscensorship", "cloudmark", "network", "solutions", "content", "based", "spam", "signatures"]} 

Was ich brauche ist es, alle doppelten URLs zählen zu tun, und drucken Sie es mögen:

http://ldrlongdistancerider.com/bikers_rights_motorcycle/rightsriders0163.php" 1 

Wie kann ich diese mit Hilfe von Streams erreichen? Übrigens muss ich die Datensätze basierend auf dem Zeitstempel filtern. Wenn jemand eine Reihe von Daten weitergegeben hat, müsste ich die URLs zählen, die in diesen Bereich fallen. Ich habe das meiste davon gemacht, aber dieser zählende Teil ist für mich verwirrend. Hier

ist, was ich bisher getan haben:

for (Path filePath : files) { 
     try { 
      Files.lines(Paths.get(filePath.toUri())) 
       .filter(s -> Link.parse(s).timestamp() > startSeconds) 
       .filter(s -> Link.parse(s).timestamp() < stopSeconds) 
       .forEach(s -> countMap.put(Link.parse(s).url(), 1)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

countMap ist HashMap von String, Integer

+1

Sie verwenden könnte 'Karte (Link :: parse)' zu vermeiden alles dreimal Parsen. – Bubletan

+0

kann ich nicht wirklich, da ich die URLs basierend auf dem Zeitstempel zuerst filtern muss. Die Verwendung einer Methodenreferenz wird mir nicht wirklich geben, was ich brauche. – Bytekoder

Antwort

4

Sie mehrere Male Parsen, und Sie verändern eine externe Karte anstelle der der Vermietung streamen die Karte für Sie erstellen, die ein Anti-Muster (es macht es schwierig, den Strom parallel zu machen)

Sie nur verwenden könnte

Files.lines(Paths.get(filePath.toUri())) 
    .map(Link::parse) 
    .filter(link -> link.timestamp() > startSeconds && link.timestamp() < stopSeconds) 
    .collect(Collectors.groupingBy(Link::url, Collectors.counting())); 
0
countMap = Files.lines(Paths.get(filePath.toUri())) 
       .filter(s -> Link.parse(s).timestamp() > startSeconds) 
       .filter(s -> Link.parse(s).timestamp() < stopSeconds) 
       .collect(Collectors.groupingBy(x ->Link.parse(x).url())) 
       .entrySet() 
       .stream() 
       .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().size())); 

Das ist, was ich tun endete und es funktioniert. Ja, ich brauchte auf dem Parsen Problem arbeiten @JB Nizet