1

如果可能的话,如何在 Java 中创建每个维度具有不同原始数据类型的静态多维数组?

我所说的静态,是指不像 ArrayList 那样动态的原始数组。

4

5 回答 5

2

你不能。

根据定义,多维数组是数组数组的数组...... 因此,除了最后一个维度之外,这些维度中的任何一个都无法成为数组以外的任何维度。至少,无论如何,按照传统定义。但是,如果您通过“多维数组”表示其他意思,您需要告诉我们那是什么。

至于“静态”,这是编程中一个严重超载的词,我能想到的每一种语言都用它来表示稍微不同的东西。在 Java 中,static意味着“属于一个类,而不是该类的实例”。同样,如果您在这里所说的“静态”指的是其他意思,您需要告诉我们那是什么。

编辑:正如最初发布的那样,问题不包括“原始”一词。这有点改变。事实上,我同意从方便的角度来看,如果 Java 允许数组被索引char或什至索引enum而不是仅仅int. 但事实并非如此。

于 2011-10-28T02:43:10.960 回答
1

经过一些测试,我有一个简单的解决方案:

Object [][] array = new Object [10][2];
array[0][0] = 2;
array[0][1] = false;
于 2011-10-28T02:50:12.113 回答
1

数组中的维度始终来自 int 类型。想想吧!

int a = 4;
int b = 5;

Shoe shoe = new Shoe (Color.RED, 42, "Leather");
Hat hat = new Hat (17, Color.Black);

Foo foo = foos[a][b];
Zilch pop = bars[shoe][hat]; // no go

如果你有一个 Foos 的多维数组,第一维是 Foo,第二维是 Foos 数组,第三维是 Foo 数组。唯一的变量类型是底部的类型。

问题更新后编辑:

数组不称为静态或原始的。它们的大小在初始化时是固定的,它们与原语的共同点是,它们是内置的,在某些情况下被威胁为特殊。它们是 - 与所谓的原始类型相反,它们不是原始类型(例如,它们具有专门用于它们自己的运算符,例如* / -)但同时它们是对象,但未在库中声明。

打电话给他们build in-types

使用 Bhesh Gurung 的技巧:

Object[] arr = {new Integer[]{}, new String[]{}, new Double[]{}}; 

是自找麻烦,而且不是每个维度由不同的数据类型组成的。让我们从尺寸开始:

// One-dimensional object:
JPanel [] panels = new JPanel [3]; 
// Two-dimensional object:
JPanel [][] panels = new JPanel [3][10]; 

您在底层有 JPanel,在下一个维度上有一个 JPanel 数组。您可以添加更多维度,并且总是会得到一个额外的 (Array of ...)。

您不能在数组中混合不同的数据类型,例如 int 和 char,或 JPanel 和 JFrame,或 int 和 JButton。仅当您对差异进行抽象,并为 JPanel 和 JFrame 使用 JComponent 作为公共父级时,但这不适用于内置类型 int、char、boolean 等,因为它们不是对象。

但是你不能用自动装箱,用Integer代替int,用Character代替char,然后用Object作为公共父类吗?是的,你可以,但是你不再使用原语,你在乞求麻烦。

Dan 在谈论不同的事情——在多维数组中使用不同的类型进行索引:

byte  b = 120;
short s = 1000;
String o [][] = new String[b][s];
b = 7;
s = 9;  
o[b][s] = "foobar";
String foo = o[b][s];

使用 bytes 或 short 没有问题,但是您不能通过将 Array 声明为 byte 或 short 来限制它的大小。在大多数情况下,内置整数类型的边界不适合数据类型(想想每年 365 天),尤其是因为所有类型都可能变为负数,所以边界检查是必要的,但不能仅限于编译时间。

但现在麻烦了:
我们可以从一开始就将数组声明为二维:

Object[][] ar2 = {
    new Integer [] {4, 5, 6}, 
    new String [] {"me", "and", "you"}, 
    new Character [] {'x', 'y', 'z'}};

这很好用,并且无需强制转换即可立即访问内部数组。但是只有编译器知道元素是对象数组——底层类型被抽象掉了,所以我们可以写:

ar2[1][1] = 17; // expected: String
ar2[2][0] = "double you"; // expected: Char

这将完美地编译,但是您正在自找麻烦并免费获得运行时异常。

这里是一个整体的来源:

public class ArrOfMixedArr
{
    public static void main (String args[])
    {
        Object[] arr = {
            new Integer [] {1, 2, 3}, 
            new String [] {"you", "and", "me"}, 
            new Character [] {'a', 'b', 'c'}};
        show (arr);
        
        byte b = 7;
        short s = 9;
        String o [][] = new String[200][1000];
        o[b][s] = "foobar";
        String foo = o[b][s];
        
        Object[][] ar2 = {
            new Integer [] {4, 5, 6}, 
            new String [] {"me", "and", "you"}, 
            new Character [] {'x', 'y', 'z'}};
        show (ar2);

        // exeptions:
        ar2[1][1] = 17; // expected: String
        ar2[2][0] = "double you"; // expected: Char
    }

    public static void show (Object[] arr)
    {
        for (Object o : arr) 
        {
            if (o instanceof Object[])
                show ((Object[]) o);
            else 
                System.out.print (o.toString () + "\t");
        }
        System.out.println ();
    }
}

现在解决方案是什么?如果您的 (int, byte, char, String, JPanel, ...) 的基本类型数组长度相等,那么您就有了类似于隐藏对象、数据库行的东西。改用一个类:

class Shoe {
    byte size;
    String manufactor;
    java.math.BigDecimal price;
    java.awt.Color color;
}

Shoe [] shoes = new Shoe [7];

如果你没有相同大小的不同类型,它们可能是不相关的,不应该放在一个公共容器中。

于 2011-10-28T02:53:35.860 回答
0

好吧,你可以定义一个数组的数组......一个对象数组(嵌套的级别与维度一样多)并在底层用不同的类型填充每个数组......然后,当你需要提取一个值,将其转换为适当的类型。为有价值的东西付出太多的工作,真的。Java 不适合这种事情,因为它是一种静态类型的语言。

也许您应该重新考虑一下,为什么需要这样的数据结构。

于 2011-10-28T02:52:33.640 回答
0

您可以通过使用对象数组来获得效果:

final static Object tryit[][] = {
        {'a',4},
        {'b',7},
        {'c',8},
};
@Test
public void accessArray( ) {
    for (int i = 0; i < tryit.length ; i++) {
        char letter = (Character)tryit[i][0];
        int value = (Integer)tryit[i][1];
        System.out.println(letter + " has value " + value);
    }
}

“@Test”是JUnit注释。

请注意,如果在数组中输入了错误的数据,则此方法在运行时会受到 NullPointer 和 ClassCast 异常的影响。

于 2015-05-14T12:47:36.697 回答