在Java中使用'new'表示数组

jav*_*ava 24 java arrays

我一直在做一些基础教程.其中一个要求我设置一个数组来保存以下字符串值:

Beyonce (f)
David Bowie (m)
Elvis Costello (m)
Madonna (f)
Elton John (m)
Charles Aznavour (m)
Run Code Online (Sandbox Code Playgroud)

写一个程序循环,计算有多少是男歌手,有多少是女性,并在控制台显示我的答案.

我设法完成它,但我设置我的阵列的方式与提供的答案不同.

我的如下:

String names[] = {"Beyonce (f)", "David Bowie (m)", "Elvis Costello (m)", "Madonna (f)", "Elton John (m)", "Charles Aznavour (m)"};
Run Code Online (Sandbox Code Playgroud)

提供的答案是这样的:

String[] singers = new String[6];
singers[0] = "Beyonce (f)";
singers[1] = "David Bowie (m)";
singers[2] = "Elvis Costello (m)";
singers[3] = "Madonna (f)";
singers[4] = "Elton John (m)";
singers[5] = "Charles Aznavour (m)";
Run Code Online (Sandbox Code Playgroud)

我应该创建一个"新"阵列吗?如果是这样,为什么?这两者有什么区别?

Smu*_*tje 35

你的答案是等同的,但更具可读性且不易出错,因为你不需要为每个数组元素提供任何"魔术数字",因为"担心"从数组定义中访问元素并因此创建一个IndexOutOfBoundsException.


Ber*_*eri 12

两者都在做同样的事情.

第一种方法更具活力.您告诉java编译器这些元素将创建一个数组.编译器在编译时知道它们的长度,因此它创建一个数组以适应它们.

在第二次尝试中,您首先要创建一个长度为6的数组.然后在每个插槽中放入一个对象.

何时使用它们:

  • 如果您从一开始就知道阵列中有哪些元素,请使用第一个方法 - 它更干净,更短
  • 但如果有某种逻辑确定谁应该放在每个槽中,那么第二个会更好.比如,当你想要创建一个10大小的数组时,你会在运行时填充它.
  • 第一个aproach也更安全,因为编译器根据输入长度创建了数组.在代码中添加新元素将改变数组大小.在第二个方法中你必须手动改变大小,否则在添加歌手时会抛出ArrayOutOfBoundException [6].
  • 但是如果你不知道数组的长度(你将在运行时填充列表),那么你必须使用List或其他动态结构(Set,List)


Era*_*ran 6

两者都是初始化数组的有效方法.

初始化数组的方法只能在定义数组变量的同一个表达式中完成,尽管稍后可以用类似的方式完成:

String[] names = null;
names = new String[] {"Beyonce (f)", "David Bowie (m)", "Elvis Costello (m)", "Madonna (f)", "Elton John (m)", "Charles Aznavour (m)"};
Run Code Online (Sandbox Code Playgroud)

提供的答案显式创建一个字符串数组,指定此数组可以存储的字符串数,并将值分配给数组的索引.

  • 我个人认为这是一种糟糕的编码风格,因为你创建了一个状态,你的应用程序对变量`names`有两种不同的设置,具体取决于程序的状态 - 如果变量在第一次变化后没有改变(或应该改变)赋值,我更喜欢最终变量. (9认同)
  • 至少你不应该用`null`初始化数组,而只是声明它.这样,编译器会告诉您在为其分配"好"值之前是否尝试使用它. (4认同)

Cod*_*dor 5

两种方案都是正确的.第一个使用数组初始值设定项,第二个首先实例化数组,然后用值填充它.有人可能会争辩说第一种解决方案更稳健,因为在第二种解决方案中,必须在提供条目之前明确给出数组的长度,并且可以使用数据的容量以及仅在数组中检测到的索引.运行.


icz*_*cza 5

可以使用new运算符创建一个新数组,后跟数组元素类型和[ ]字符之间的数组大小- 这称为数组创建表达式.或者当你声明一个变量,你也可以使用文本阵列被称为数组的初始化(但不能用于分配的值到一个数组以后只是当它被声明).

当你写作

String names[] = {"A", "B", "C"};
Run Code Online (Sandbox Code Playgroud)

它只是一个简短的形式,相当于

String[] names = new String[] {"A", "B", "C"};
Run Code Online (Sandbox Code Playgroud)

请注意,要指示要声明指定类型的数组,可以使用它们String[] namesString names[]形式,它们是等效的,尽管如此:

String names[], names2; // Only names is an array, names2 is just a String
Run Code Online (Sandbox Code Playgroud)

String[] names, names2; // Both names and names2 are arrays!
Run Code Online (Sandbox Code Playgroud)

如果以后在声明中添加更多变量名,建议使用第二种形式以避免混淆和意外.

让我们仔细看看这两种情况会发生什么:

// "Slow" filling
String[] names = new String[3]; // Filled with null values by default
names[0] = "A"; // Explicit index, index range check!
names[1] = "B"; // Explicit index, index range check!
names[2] = "C"; // Explicit index, index range check!

// "Fast" filling at creation time, implicit indices and array length,
// No index checks!
String[] names = {"A", "B", "C"};
Run Code Online (Sandbox Code Playgroud)

一步创建和初始化阵列的优点

在一个步骤中创建和初始化数组有几个优点:

  • 这样做不太容易出错:编译器将确定数组的长度,编译器也会根据您提供的列表初始化数组的元素.没有使用错误的索引值或得到一个ArrayIndexOutOfBoundsException.
  • 它会更快,因为JVM(Java虚拟机)不会使用null值初始化数组.
  • 它会更快,因为您不必指定显式索引值,并且JVM不必使用它们.此外,JVM不必检查索引是否在有效范围内(即0..length-1).
  • 当您想要在数组中间添加另一个元素时,更少的维护/开销,您只需将其插入所需的位置即可.您是否已经以其他方式初始化了数组,您必须更新所有后续索引.
  • Java源代码将更短,更紧凑,并且编译的字节代码也将更短.

您可以在Java语言规范中阅读有关数组的更多信息:第10章.数组