在Java中高效存储包含基元的对象数组

时间:2011-10-06 07:50:18

标签: java c arrays

将以下数据结构从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)
}

但它使用太多的对象来保存简单的基元。

7 个答案:

答案 0 :(得分:3)

  

但它使用太多的对象来保存简单的基元。

不,它没有。 Java intdouble字段不是对象;它将作为其包含Foo实例的一部分在堆上分配。

因此,在您的情况下,将有101个对象:一个Foo[]数组和100个Foo个实例。

或者你想要所有这些都是一个“扁平”阵列?对不起,没有用Java做的,那不是它的工作原理。

那么,你到底在想什么呢? 101这类对象 nothing ,我们在这里讨论的不到4KB!

答案 1 :(得分:2)

使用5个并行数组可能是您管理它的最有效的内存方式。

但是处理它会更加复杂 更加复杂,你可以轻松地引入错误,除了它不像OO一样(即你不能轻松利用Java提供的有用功能这样的构造)。

所以我尝试这样做,如果明显的映射(创建一个类并创建该类型的数组)可以证明有问题。

如果使用并行数组方法,那么您可以创建一个Foo类作为这些数组的外观对象:它采用索引i并执行通过透明地引用适当的数组,好像它是一个单一的结构。

答案 2 :(得分:1)

在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 };

答案 3 :(得分:1)

重新提出你的问题:“在Java中存储保存基元的对象数组是高效的”。你甚至不应该问自己这样的问题:数组,集合和对象是可行的方法,在没有事后的情况下使用它们。

答案 4 :(得分:1)

我会说:别担心。

32位JVM中Foo对象的大小是

8字节对象开销+ 4 *(int字段为4字节)+ 1 *(双字段为8字节)= 32字节

因此对象开销为25%。有很多方法可以有效地使用Java NIO缓冲区,但除非你处理大量数据,否则它很少有价值。

答案 5 :(得分:0)

我不认为这应该是一个问题。这个级别并不比其领域所需的空间大。您当然可以使用数组来存储所有值,但是您必须搜索数组才能找到某些内容。

答案 6 :(得分:0)

您可以查找在线转换器或编写一个简单的程序,该程序使用regexp从c源文件中捕获数据并生成java代码。