#java #c #arrays
#java #c #массивы
Вопрос:
Какой наиболее эффективный способ преобразовать следующую структуру данных из C в Java?
struct {
int a; int b; int c; int d;
double e;
} foo[] = {
{ 0, 1, 2, 42, 37.972},
/* ... 100 more struct elements ... */,
{ 0, 3, -1, -4, -7.847}
}
Лучшее, что я мог придумать, это:
class Foo {
public int a;
public int b;
public int c;
public int d;
public double e;
public Foo(int a, int b, int c, int d, double e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
}
Foo[] foo = new Foo[] {
new Foo(0, 1, 2, 42, 37.972),
/* ... 100 more objects ... */
new Foo(0, 3, -1, -4, -7.847)
}
Но он использует слишком много объектов для хранения простых примитивов.
Ответ №1:
Но он использует слишком много объектов для хранения простых примитивов.
Нет, это не так. Java int
или double
поле не является объектом; оно будет размещено в куче как часть содержащего Foo
его экземпляра.
Итак, в вашем случае будет 101 объект: один Foo[]
массив и 100 Foo
экземпляров.
Или вы хотите, чтобы все это было одним «плоским» массивом? Извините, на Java это невозможно, так это не работает.
Опять же, о чем именно вы беспокоитесь здесь? 101 Объект такого рода — это ничто, мы говорим здесь о менее чем 4 КБ!
Комментарии:
1. Да, я надеялся, что смогу сделать его плоским вместо использования 101 объекта. Это так просто сделать на C.
2. @Dheeraj: ну, если вам нужен C, вы знаете, где его найти… Серьезно, в чем проблема? Служебный объем объекта составляет 8 байт. Поскольку ваши примеры объектов имеют полезную нагрузку в 24 байта, это накладные расходы на 33%. Не идеально, но вряд ли драматично, и, конечно, не стоит беспокоиться, если у вас нет миллионов объектов (и даже тогда поиск способа уменьшить это число может быть гораздо более эффективным).
3. Спасибо за информацию. Исходя из встроенного фона C, я был параноиком.
4. @Dheeraj: Ах, это все объясняет 🙂
Ответ №2:
Использование 5 параллельных массивов, вероятно, является наиболее эффективным с точки зрения памяти способом управления этим.
Но с этим будет намного сложнее справиться, и вы можете слишком легко вводить ошибки, кроме того, что это не очень похоже на OO (т. Е. Вы не можете легко использовать полезные функции, которые Java предоставляет с такой конструкцией).
Поэтому я бы попытался пойти этим путем, только если можно доказать, что очевидное сопоставление (создание класса и создание массива этого типа) является проблематичным.
Если вы используете подход с параллельными массивами, то вы можете создать Foo
класс, который действует как фасадный объект для этих массивов: он принимает индекс i
и действует так, как если бы это была единая структура, прозрачно ссылаясь на соответствующие массивы.
Ответ №3:
В вашем массиве структур C вы должны сначала выбрать, какую строку вы хотите, а затем какой столбец (a, b, c, d, e). Вы могли бы использовать аналогичное пространство для хранения в Java, используя отдельный массив для каждого столбца:
int[] a = new int[] { 0, ..., 0 };
int[] b = new int[] { 1, ..., 3 };
int[] c = new int[] { 2, ..., -1 };
int[] d = new int[] { 42, ..., -4 };
double[] e = new double[] { 37.972, ..., -7.847 };
Ответ №4:
Перефразируя ваш вопрос: «Хранение массива объектов, содержащих примитивы в Java, эффективно». Вы даже не должны задавать себе такие вопросы: массивы, коллекции и объекты — это правильный путь, используйте их без запоздалой мысли.
Ответ №5:
Я бы сказал: не беспокойтесь об этом.
Размер объекта Foo в 32-разрядной виртуальной машине равен
8 байт служебных данных объекта 4 * (4 байта для полей int) 1 * (8 байт для двойных полей) = 32 байта
Таким образом, накладные расходы на объект составляют 25%. Существуют способы эффективного использования памяти с буферами Java NIO, но это редко стоит того, если вы не имеете дело с огромными объемами данных.
Ответ №6:
Я не думаю, что это должно быть проблемой. Класс не намного больше, чем пространство, необходимое для его полей. Конечно, вы могли бы использовать массив для хранения всех значений, но тогда вам придется искать в массиве, чтобы что-то найти.
Ответ №7:
Вы можете найти онлайн-конвертер или написать простую программу, которая использует регулярное выражение для сбора данных из исходного файла c и генерации кода Java.