Обработка больших списков строк в java

У меня есть задача, где я должен пройти через несколько миллиардов строк и проверить, является ли каждая из них уникальной. Все линии сами по себе не могут быть размещены в оперативной памяти ПК. Кроме того, количество строк, вероятно, будет больше, чем целое число.МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ.

Я предполагаю, что лучший способ обработать этот объем данных-поместить хэш-коды каждой из строк в какую-то хэш-таблицу.

Итак, вот мои вопросы:

  1. что я должен использовать вместо String.hashCode()? (возвращаемое значение-int, но мне, вероятно, понадобится long)
  2. каков самый быстрый способ / фреймворк для работы со списками такого размера? Что мне больше всего нужно, это возможность быстро проверить, содержит ли список элемент или нет

2 ответов


вы слишком думаете о проблеме, все это можно сделать очень просто с одной таблицей MySQL, которая сохраняет данные на диск, а не держит все в памяти. Такое количество данных никогда не предназначалось для эффективной обработки автономным приложением.

CREATE TABLE TONS_OF_STRINGS
(
  unique_string varchar(255) NOT NULL,
  UNIQUE (unique_string)
)

просто переберите значения (при условии, что список разделен запятыми) и попробуйте вставить каждый токен. Каждый неудачный токен является дубликатом.

public static void main(args) {
  Connection con = DriverManager.getConnection("jdbc:mysql://localhost/database","username","password");
  FileReader file = new FileReader("SomeGiantFile.csv");
  Scanner scan = new Scanner(file);
  scan.useDelimiter(",");
  String token;
  while ( scan.hasNext() ) {
    token = scan.next();
    try {
      PreparedStatement ps = con.prepareStatement("Insert into TONS_OF_STRING (UNIQUE_STRING) values (?)");
      ps.setString(1, token);
      ps.executeUpdate();
    } catch (SQLException e) {
      System.out.println("Found duplicate: " + token );
    }
  }
  con.close();
  System.out.println("Well that was easy, I'm all done!");
  return 0;
}

Не забудьте очистить таблицу, когда вы закончите хотя, это много данных.


недостаточно просто хранить 32 или 64-битные хеш-коды, потому что две разные строки (из нескольких миллиардов) могут легко иметь один и тот же хеш-код. Как только у вас есть две строки с одним и тем же хэш-кодом, вам нужно сравнить фактические строки, чтобы увидеть, действительно ли они равны.

вот как я бы решил эту проблему:

  1. прочитайте файл / поток строк:

    1. читать каждая линия

    2. вычислить хэш-код для строки

    3. напишите хэш-код и строку во временный файл с подходящим разделителем полей между

  2. используйте приличную внешнюю программу сортировки для сортировки временного файла, используя поле хэш-кода в качестве первичного ключа сортировки и поле строки в качестве вторичного ключа сортировки.

  3. прочитайте временный файл по строке за раз. Если два последовательные строки имеют одно и то же поле хэш-кода и разные строковые поля, тогда вы нашли повторяющуюся строку.

Примечание: этот подход будет одинаково хорошо работать с 32 или 64-битными хэш-кодами.