Предполагая, что все ваши строки имеют большинство одинаковых столбцов, вы можете просто использовать массив для каждой строки и Map для поиска, какие столбцы ссылаются на какую ячейку. Таким образом, у вас есть только 4-8 байтов служебной информации на ячейку.
Если строки часто повторяются, вы можете использовать пул строк, чтобы уменьшить дублирование строк. Пулы объектов для других неизменяемых типов могут быть полезны для сокращения потребляемой памяти.
РЕДАКТИРОВАТЬ: Вы можете структурировать данные как на основе строки или столбца. Если его строки основаны (один массив ячеек на строку), добавление / удаление строки - это просто вопрос удаления этой строки. Если его столбцы основаны, вы можете иметь массив для каждого столбца. Это может сделать обработку примитивных типов намного более эффективной. т. е. у вас может быть один столбец с типом int [], а другой с двойным [], гораздо чаще для всего столбца используется один и тот же тип данных, чем для одного и того же типа данных для всей строки.
Тем не менее, в любом случае вы будете обрабатывать данные, которые будут использоваться для модификации строк или столбцов, а выполнение добавления / удаления другого типа приведет к перестройке всего набора данных.
(Что-то, что я делаю, это имею данные на основе строк и добавляю столбцы в конец, при условии, что если строка недостаточно длинна, столбец имеет значение по умолчанию, это позволяет избежать перестроения при добавлении столбца. Вместо удаления столбца , У меня есть способ игнорировать это)