Найти самые большие цены среди огромного количества файлов CSV - PullRequest
0 голосов
/ 16 января 2019

У меня есть 100 CSV-файлов со следующим содержанием

name,price
book,12.4
bread,54.23

В каждом файле показывается контент в порядке цен Мне нужно найти 10 самых дорогих продуктов через все эти файлы. Это мой код:

import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import static java.util.stream.Collectors.toList;

public final class FindBiggest extends Assert {

    static class Data {
        public Data(String str) {
            final String[] split = str.split(",");
            this.name = split[0];
            this.price = Float.parseFloat(split[1]);
        }

        private final String name;
        private final float price;
    }

    @Test
    public void test() throws Exception {
        final List<File> files = Files.walk(Paths.get("/tmp/"))
                .filter(Files::isRegularFile)
                .filter(path -> path.toString().endsWith(".csv"))
                .map(Path::toFile)
                .collect(toList());
        final List<Data> collect =
                files.stream()
                        .map(FindBiggest::content)
                        .map(Data::new)
                        .sorted((o1, o2) -> Float.compare(o1.price, o2.price))
                        .limit(10)
                        .collect(toList());
        System.out.println(collect);

    }

    private static String content(final File file) {
        try {
            return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

}

В случае, если у меня много csv-файлов, программа выдает UOM (Out of memory), как реализовать программу для сортировки содержимого во всех файлах без загрузки всех данных в память?

1 Ответ

0 голосов
/ 18 января 2019

Вам понадобится некоторый отсортированный набор, ограниченный определенным количеством предметов. Возможно, некоторые библиотеки сторонних коллекций предоставляют его, в противном случае вы можете сделать это как-то так: Limited SortedSet . Важно то, что метод add такого отсортированного набора должен возвращать false, если коллекция заполнена, а добавленный элемент выходит за пределы, и true в противном случае.

Теперь сделайте цикл над файлами CSV. Внутри тела цикла читайте записи из файла CSV и добавляйте их в набор до тех пор, пока add не вернет false (это будет означать, что коллекция заполнена, и никакие новые записи из текущего CSV не будут больше, чем текущие - время перейти к следующему файлу).

Когда цикл будет завершен, ответом будет результирующий набор.

...