Java: карта карт с одинаковыми ключами - PullRequest
1 голос
/ 05 марта 2012

Рассмотрим огромный CSV со следующей структурой (модифицированной для простоты):

ID, NAME,  ADDRESS, PHONE, MAIL
1,  Jon,   UK,      403,  jon@skeet.com
2,  Marc,  UK,      292,  marc@gravel.com
3,  Darin, France,  291,  darin@dimitrov.com
...
(Some million records)

Естественная структура данных для быстрой выборки - это хэш-таблица, где каждый ID является ключом, а NAME, ADDRESS, PHONE, MAIL - значением. Моя дилемма - это структура данных значений.

Хранение в HashMap, где каждый заголовок строки является ключом, является пустой тратой пространства, потому что заголовки строк одинаковы для каждой строки. Хранение его в виде массива приведет к потере метаданных для каждого элемента, потому что читатель

Я думал о двух подходах:

  • Перегрузить хэш-карту Java. Заголовки строк будут сохранены один раз, и каждый ID будет связан с массивом строк. Метод get() будет перегружен, поэтому он вернет карту между строками заголовка и соответствующими полями в строке.

  • Создать тупой класс, который хранит данные для каждой строки, используя геттеры и сеттеры (row.getMail(), row.getAddress(), ...)

Какой правильный путь с точки зрения эффективности памяти, безопасности типов и скорости?

Ответы [ 3 ]

2 голосов
/ 05 марта 2012

Хотя класс 'тупой' является более чистым подходом, он, очевидно, менее универсален, чем подход с использованием карт, и потребует логики синтаксического анализа, специфичной для формата CSV - так что есть компромисс.

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

2 голосов
/ 05 марта 2012

Я бы выбрал "тупой" класс вместо перегрузки коллекции.

Я не знаю о безопасности типов и скорости, но я бы сказал, что ваш код будет более читабельным.Эти ценности идут вместе;заключить их в объект, чтобы подчеркнуть суть.Есть ли какое-либо поведение, связанное с ними, кроме get / set?Если да, то тем лучше.

1 голос
/ 05 марта 2012

Я бы не стал беспокоиться о потраченном впустую месте, если вы не знаете, что у вас есть проблема. у вас много ГБ данных.

Если вы хотите узнать, как сделать его более эффективным, вы можете использовать комбинацию Map<String, Integer> для поиска ключей и использовать Object[] для каждой строки. Для поиска по имени вы найдете номер, который нужно найти первым.

Еще более эффективный подход - хранить данные по столбцам, а не по строкам. Это более эффективно, так как у вас больше строк, чем столбцов

Map<String, List> columns = ...

Вы можете искать ячейку сначала по имени, а затем по записи в списке. Если вы хотите использовать примитивные типы, вы можете использовать int[] или double[] или TIntArrayList и TDoubleArrayList для экономии памяти. Страна ADDRESS может иметь перечислимый тип.

Если бы у вас не было миллионов строк, я бы просто упростил.

...