azerphoenix
@azerphoenix
Java Software Engineer

Как избежать дублирования итерации при использовании parallel()?

Доброго времени суток!

Постараюсь вкратце описать проблему.
Имеется следующий сниппет:
LongStream.range(1L, 10000000L)
.parallel()
.mapToObj(String::valueOf)
.forEach(index -> {

    try {

        String url = "http://example.com?ID=" + index;
        driver.get(url);

        if (driver.getStatusCode() == 200) {

            System.out.println("Opening URL: " + url);

            String pageSource = driver.getPageSource();
            Document doc = Jsoup.parse(pageSource);

            Elements centerBox = doc.select(".center-box");

            if (!centerBox.isEmpty()) {

                String name = centerBox.select("[data-bind=text: name]").text();
                String email = centerBox.select("[data-bind=text: email]").text();

                Company company = new Company(name, email);
                System.out.println("Info: \n" +
                        url + "\n" +
                        name + "\n" +
                        email);
                companies.add(company);


                PrintWriter pw = new PrintWriter(new FileWriter(pathToFile, true));
                pw.println(name + "\t" + email);
                pw.close();

            } else {

                System.out.println("URL not found: " + url);

            }

        }

    } catch (Exception e) {
        e.printStackTrace();
    }

});
driver.quit();


При запуске этого скрипта наблюдается следующее...
1) В List добавляются дублирующиеся объекты Company
2) В файл (PrintWriter) добавляются дублирующиеся строки.
3) В URL объекта Company подставляются не те урлы, по которым была найдена информация, а другие урлы и параллельного потока, в которых нет информации....

Как решить эти вопросы? И можно ли упростить этот код, чтобы например, не создавать объект Company и не добавляет в список, а например использовать collect toList и т.д.

Заранее спасибо за помощь!
  • Вопрос задан
  • 76 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
Вы неправильно используете стримы. В них не должно изменяться внешнее состояние. Вашу пелёнку кода внутри forEach можно разбить на небольшие идемпотентные операции и собрать их результат с помощью коллектора.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы