如果可能的话,如何在 Java 中创建每个维度具有不同原始数据类型的静态多维数组?
我所说的静态,是指不像 ArrayList 那样动态的原始数组。
如果可能的话,如何在 Java 中创建每个维度具有不同原始数据类型的静态多维数组?
我所说的静态,是指不像 ArrayList 那样动态的原始数组。
你不能。
根据定义,多维数组是数组数组的数组...... 因此,除了最后一个维度之外,这些维度中的任何一个都无法成为数组以外的任何维度。至少,无论如何,按照传统定义。但是,如果您通过“多维数组”表示其他意思,您需要告诉我们那是什么。
至于“静态”,这是编程中一个严重超载的词,我能想到的每一种语言都用它来表示稍微不同的东西。在 Java 中,static
意味着“属于一个类,而不是该类的实例”。同样,如果您在这里所说的“静态”指的是其他意思,您需要告诉我们那是什么。
编辑:正如最初发布的那样,问题不包括“原始”一词。这有点改变。事实上,我同意从方便的角度来看,如果 Java 允许数组被索引char
或什至索引enum
而不是仅仅int
. 但事实并非如此。
经过一些测试,我有一个简单的解决方案:
Object [][] array = new Object [10][2];
array[0][0] = 2;
array[0][1] = false;
数组中的维度始终来自 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];
如果你没有相同大小的不同类型,它们可能是不相关的,不应该放在一个公共容器中。
好吧,你可以定义一个数组的数组......一个对象数组(嵌套的级别与维度一样多)并在底层用不同的类型填充每个数组......然后,当你需要提取一个值,将其转换为适当的类型。为有价值的东西付出太多的工作,真的。Java 不适合这种事情,因为它是一种静态类型的语言。
也许您应该重新考虑一下,为什么需要这样的数据结构。
您可以通过使用对象数组来获得效果:
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 异常的影响。