2015-05-12 8 views
2

У меня есть данные, структурированные в виде таблицыЗаказал столик структура данных

+------+------+------+------+ 
|  | Col1 | Col2 | Col3 | 
+------+------+------+------+ 
| Row1 | 1 | 2 | 3 | 
| Row2 | 5 | 5 | 6 | 
| Row3 | 9 | 2 | 7 | 
+------+------+------+------+ 

я ищу структуру данных, которая позволяет следующее:

  • Быстрая итерация столбца и строки (получить значения для столбца или строк. (Не стоит дорожать итерацией в одном направлении, чем в другом)
  • Быстрое добавление и удаление целых строк и столбцов (снова обе операции должны быть одинаково быстрыми и должны быть не более O (n))
  • Заказ на основе заказа на размещение и переупорядочивания. Заказ будет рассчитываться с помощью некоторых компараторов и обычно зависит от данных в строке или столбце, но не от каких-либо имен или таких
  • Хранить данные, отличные от цифр (У нас есть смешанные данные, но я планирую использовать класс контейнера для фактические данные в любом случае)

Кроме того, строки и столбцы будут иметь метаданные (имя, цвет и тому подобное). Все эти операции часто происходят в нашей системе. В настоящее время мы сохраняем строку данных на основе, и в столбцах нет ссылки на связанные с ними данные. Это делает удаление столбца или повторение его данных очень утомительным.

Первое, что возникло у меня в голове, это Guava Table, но это не упорядочено, и я не уверен, что легко удалить целую строку или столбец, хотя это может сделать очистка карты строк или столбцов.

Массивы в качестве хранилища для хранения не будут работать из-за необходимости добавления и удаления. (Хотя я мог бы предсказать, насколько большой будет таблица, и создать новые таблицы для удаления, но мне не нравится это решение, даже если оно может быть скрыто от пользователя)

Я был бы признателен за любые идеи относительно как реализовать такую ​​структуру данных.

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

+0

Просьба уточнить, что такое «заказ» в вашем случае? –

+0

Другой вопрос: вам нужен O (1) доступ по индексу или O (k) в порядке (k - количество столбцов/строк)? –

+0

Для доступа по индексу O (k) все в порядке, мы не часто это делаем (хорошо, технически мы делаем, потому что мы не можем перебирать столбцы, но это то, что я хотел бы изменить). Обычно заказ выполняется по порядку размещения, хотя в конце мы обычно упорядочиваем по строке или столбцу (строка с наибольшим результатом в верхнем или столбце слева) – Chris

ответ

3

Guava Table s может быть заказан. ImmutableTable предоставляет «надежный пользовательский порядок итераций» и (из документов Builder) «по умолчанию порядок добавления ячеек в конструктор определяет порядок итераций всех представлений в возвращенной таблице».

Или TreeBasedTable может использоваться, если вам необходимо изменить код Table и хотите получить RowSortedTable.

Вы также можете реализовать свой собственный класс LinkedHashBasedTable довольно легко. Либо с ForwardingTable и LinkedHashSet, чтобы сохранить желаемый порядок итерации, либо просто позвоните Tables.newCustomTable() с LinkedHashMap в качестве первого аргумента (и результат Supplier, если необходимо).


Большинство Table реализации обеспечивает O (1) или О (п) (где п строка/счетчик Colum) реализация для всех стандартных методов, а также методы, которые возвращают вид (например, row() и colum()) являются напрямую поддерживаемые оригиналом Table, поэтому они также эффективны.

Если вы действительно обеспокоены тем, что все доступные версии Table (включая .newCustomTable()) являются слишком медленными, вы должны сравнить это. Они более чем достаточно эффективны для всех нормальных применений, и без доказательства того, что Table s - это ваше узкое место, создающее вашу собственную структуру данных, является явным примером premature optimization.

+0

Прочтите javadoc, но до сих пор не знаю, как реализовать быстрое удаление столбца с помощью этого ... –

+0

@SashaSalauyou самый чистый способ, вероятно, с 'Table.column (column) .clear()' - это O (n) (где n - количество строк), так как он должен перебирать карту строк. – dimo414

+0

Я предполагаю, что это для очистки (установка нулей или фиктивных значений для всего столбца), а не удаление. После многих вставок/удалений такая таблица будет скудной. (Я не буду критиковать, просто открывая возможности) –

0

Благодарим вас за помощь и идеи. Я пришел к выводу, что сохраню текущую структуру таблицы, состоящую из списка строк, у каждого из которых есть список ячеек. Хотя это затрудняет итерацию по столбцам или удаление столбцов, наши таблицы обычно довольно малы (< 15 строк, < 100 столбцов), и основным узким местом нашей текущей реализации является то, что данные хранятся в строках, а не набираются (Double .parse может быть довольно дорого, если вы делаете это слишком часто). Хотя было бы очень интересно разработать структуру данных, которая удовлетворяет всем требованиям в моем первоначальном вопросе, реальность такова, что я не могу потратить столько времени на работу над этим.

+0

Вы пытались использовать '.newCustomTable()' с 'LinkedHashMap'? Это должно быть намного быстрее, чем подход на основе списка. – dimo414

Смежные вопросы