我一直在做一些基础教程.其中一个要求我设置一个数组来保存以下字符串值:
Beyonce (f)
David Bowie (m)
Elvis Costello (m)
Madonna (f)
Elton John (m)
Charles Aznavour (m)
写一个程序循环,计算有多少是男歌手,有多少是女性,并在控制台显示我的答案.
我设法完成它,但我设置我的阵列的方式与提供的答案不同.
我的如下:
String names[] = {"Beyonce (f)", "David Bowie (m)", "Elvis Costello (m)", "Madonna (f)", "Elton John (m)", "Charles Aznavour (m)"};
提供的答案是这样的:
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)";
我应该创建一个"新"阵列吗?如果是这样,为什么?这两者有什么区别?
1> Smutje..:
你的答案是等同的,但更具可读性且不易出错,因为你不需要为每个数组元素提供任何"魔术数字",因为"担心"从数组定义中访问元素并因此创建一个IndexOutOfBoundsException
.
2> Beri..:
两者都在做同样的事情.
第一种方法更具活力.您告诉java编译器这些元素将创建一个数组.编译器在编译时知道它们的长度,因此它创建一个数组以适应它们.
在第二次尝试中,您首先要创建一个长度为6的数组.然后在每个插槽中放入一个对象.
何时使用它们:
如果您从一开始就知道阵列中有哪些元素,请使用第一个方法 - 它更干净,更短
但如果有某种逻辑确定谁应该放在每个槽中,那么第二个会更好.比如,当你想要创建一个10大小的数组时,你会在运行时填充它.
第一个aproach也更安全,因为编译器根据输入长度创建了数组.在代码中添加新元素将改变数组大小.在第二个方法中你必须手动改变大小,否则在添加歌手时会抛出ArrayOutOfBoundException [6].
但是如果你不知道数组的长度(你将在运行时填充列表),那么你必须使用List或其他动态结构(Set,List)
3> Eran..:
两者都是初始化数组的有效方法.
初始化数组的方法只能在定义数组变量的同一个表达式中完成,尽管稍后可以用类似的方式完成:
String[] names = null;
names = new String[] {"Beyonce (f)", "David Bowie (m)", "Elvis Costello (m)", "Madonna (f)", "Elton John (m)", "Charles Aznavour (m)"};
提供的答案显式创建一个字符串数组,指定此数组可以存储的字符串数,并将值分配给数组的索引.
我个人认为这是一种糟糕的编码风格,因为你创建了一个状态,你的应用程序对变量`names`有两种不同的设置,具体取决于程序的状态 - 如果变量在第一次变化后没有改变(或应该改变)赋值,我更喜欢最终变量.
至少你不应该用`null`初始化数组,而只是声明它.这样,编译器会告诉您在为其分配"好"值之前是否尝试使用它.
4> Codor..:
两种方案都是正确的.第一个使用数组初始值设定项,第二个首先实例化数组,然后用值填充它.有人可能会争辩说第一种解决方案更稳健,因为在第二种解决方案中,必须在提供条目之前明确给出数组的长度,并且可以使用数据的容量以及仅在数组中检测到的索引.运行.
5> icza..:
可以使用new
运算符创建一个新数组,后跟数组元素类型和[
]
字符之间的数组大小- 这称为数组创建表达式.或者当你声明一个变量,你也可以使用文本阵列被称为数组的初始化(但不能用于分配的值到一个数组以后只是当它被声明).
当你写作
String names[] = {"A", "B", "C"};
它只是一个简短的形式,相当于
String[] names = new String[] {"A", "B", "C"};
请注意,要指示要声明指定类型的数组,可以使用它们String[] names
和String names[]
形式,它们是等效的,尽管如此:
String names[], names2; // Only names is an array, names2 is just a String
而
String[] names, names2; // Both names and names2 are arrays!
如果以后在声明中添加更多变量名,建议使用第二种形式以避免混淆和意外.
让我们仔细看看这两种情况会发生什么:
// "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"};
一步创建和初始化阵列的优点
在一个步骤中创建和初始化数组有几个优点:
这样做不太容易出错:编译器将确定数组的长度,编译器也会根据您提供的列表初始化数组的元素.没有使用错误的索引值或得到一个ArrayIndexOutOfBoundsException
.
它会更快,因为JVM(Java虚拟机)不会使用null
值初始化数组.
它会更快,因为您不必指定显式索引值,并且JVM不必使用它们.此外,JVM不必检查索引是否在有效范围内(即0..length-1
).
当您想要在数组中间添加另一个元素时,更少的维护/开销,您只需将其插入所需的位置即可.您是否已经以其他方式初始化了数组,您必须更新所有后续索引.
Java源代码将更短,更紧凑,并且编译的字节代码也将更短.
您可以在Java语言规范中阅读有关数组的更多信息:第10章.数组