Java 8 Streams считает все ключи
У меня есть файл, который содержит данные в форме формата JSON. Я читаю это построчно, и каждая строка имеет 1 запись JSON, поэтому формат не является проблемой. Ниже приведен пример строки:
{"url": "http://ldrlongdistancerider.com/bikers_rights_motorcycle/rightsriders0163.php", "timestamp": 1257072412, "tags": ["nscensorship", "cloudmark", "network", "solutions", "content", "based", "spam", "signatures"]}
Что мне нужно сделать, так это сосчитать все дубликаты URL и напечатать их следующим образом:
http://ldrlongdistancerider.com/bikers_rights_motorcycle/rightsriders0163.php" 1
Как я могу добиться этого с помощью потоков? Кстати, мне нужно отфильтровать записи на основе отметки времени. Поэтому, если кто-то пропустит диапазон дат, мне придется подсчитать URL-адреса, попадающие в этот диапазон. Я сделал большую часть этого, но эта счетная часть сбивает меня с толку.
Вот что я сделал до сих пор:
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 - это HashMap из String, Integer
2 ответа
Вы анализируете несколько раз и изменяете внешнюю карту, вместо того, чтобы позволить потоку создавать карту для вас, что является анти-паттерном (затрудняет параллельный поток)
Вы могли бы просто использовать
Files.lines(Paths.get(filePath.toUri()))
.map(Link::parse)
.filter(link -> link.timestamp() > startSeconds && link.timestamp() < stopSeconds)
.collect(Collectors.groupingBy(Link::url, Collectors.counting()));
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()));
Это то, что я в итоге сделал, и это работает. Да, мне нужно было поработать над проблемой синтаксического анализа @JB Nizet