13

代码 1:

ArrayList arr = new ArrayList();
arr.add(3);
arr.add("ss");

代码 2:

ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");

代码 3:

ArrayList<Object> arr = new ArrayList<Object>();
arr.add(new Integer(3));
arr.add(new String("ss"));

以上三个代码都工作正常..有人可以告诉我哪个是首选的以及为什么..以及为什么当 Arraylist 没有提到参数类型时 eclipse 编译器总是给出警告..提前谢谢..

4

9 回答 9

11

第一个简单的规则:永远不要使用String(String)构造函数,它绝对没用(*)

所以arr.add("ss")就好了。

3它略有不同:3int文字,而不是对象。只能将对象放入List. 所以int需要将遗嘱转换为Integer对象。在大多数情况下,这将为您自动完成(该过程称为自动装箱)。在某些情况下,它可以(并且将)有效地避免创建新实例。Integer.valueOf(3)Integer

所以实际上写arr.add(3)通常使用更好arr.add(new Integer(3)),因为它可以避免创建一个新Integer对象,而是重用现有的对象。

免责声明:我在这里关注第二个和第三个代码块之间的区别,几乎忽略了泛型部分。有关泛型的更多信息,请查看其他答案。

(*) 在一些晦涩的极端情况下它很有用,但是一旦你接近那些你就会知道永远不要把绝对陈述当作绝对的;-)

于 2012-05-29T10:13:30.867 回答
6

第二个是首选:

  • 它避免了不必要/低效的构造函数调用
  • 它使您可以指定列表的元素类型(如果缺少,则会收到警告)

但是,在同一个列表中包含两种不同类型的对象会有一点不好的设计气味。我们需要更多的背景来谈论这一点。

于 2012-05-29T10:11:22.987 回答
3

第二种形式是首选:

ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");

使用泛型类型(例如ArrayList<T>)时始终指定泛型参数。这排除了第一种形式。

至于最后一种形式,它更冗长,并且无益地做额外的工作。

于 2012-05-29T10:11:31.797 回答
2

好吧,通过执行上述操作,您将自己打开运行时错误,除非您乐于接受您的数组列表可以包含字符串和整数以及大象。

Eclipse 返回一个错误,因为它不希望您不知道这样一个事实,即不为泛型参数指定任何类型会使您自己面临运行时错误。至少对于其他两个示例,您知道您可以在 Arraylist 中包含对象,并且由于 Inetegers 和 Strings 都是对象,Eclipse 不会警告您。

代码 2 或 3 都可以。但是如果你知道你的数组列表中只有整数或只有字符串,那么我会做

ArrayList<Integer> arr = new ArrayList<Integer>();

或者

ArrayList<String> arr = new ArrayList<String>();

分别。

于 2012-05-29T10:11:19.700 回答
2

实际上,第三个是首选:

ArrayList<Object> array = new ArrayList<Object>();
array.add(Integer.valueOf(3));
array.add("ss");

这避免了自动装箱(Integer.valueOf(3)vs 3)并且不会创建不必要的 String 对象。

当您不使用具有泛型类型(如 ArrayList)的类型参数时,Eclipse 会抱怨,因为您使用的是一种称为原始类型的东西,这是不鼓励的。如果一个类是泛型的(也就是说,它具有类型参数),那么您应该始终使用该类的类型参数。

另一方面,自动装箱是个人喜好。有些人可以接受,有些人则不行。我不喜欢它,我打开了自动装箱/自动拆箱的警告。

于 2012-05-29T10:13:59.883 回答
2

您收到警告是因为ArrayList它是 java 泛型的一部分。本质上,这是一种在编译时捕获类型错误的方法。例如,如果您使用类型 Integer ( ArrrayList<Integer>) 声明数组列表,然后尝试向其中添加字符串,您将在编译时收到错误 - 避免在运行时出现严重的崩溃。

第一种语法是为了向后兼容,应尽可能避免使用(请注意,旧版本的 java 中没有泛型)。

第二个和第三个例子几乎是等价的。由于您需要将对象而不是原始类型传递给add方法,因此您3在内部转换为Integer(3). 通过用双引号写一个字符串,您实际上是在创建一个String对象。调用时String("ss"),您正在创建一个String值与参数(“ss”)相同的新对象。

除非您确实需要在列表中存储不同的类型,否则我建议您实际使用正确的类型声明,例如ArrayList<Integer> = new ArrayList<Integer>()- 从长远来看,它会为您省去很多麻烦。

如果您确实需要列表中的多种数据类型,那么第二个示例会更好。

于 2012-05-29T10:16:31.750 回答
2

最后两个变体是相同的,int会自动包装到Integer您需要Object. 如果您没有在 <> 中编写任何类,则Object默认情况下。所以没有区别,但是如果你写的话会更好理解Object

于 2012-05-29T10:16:46.757 回答
2

在 Java 9 中有一种更快、更简单的方法,不需要太多代码:使用Collection Factory方法:

List<String> list = List.of("first", "second", "third");
于 2018-04-10T09:08:57.670 回答
0

首先,您没有定义将在您的 arraylist 构造中保存和链接的类型

这是这样做的首选方法,您定义列表的类型,ide 将处理其余的

在第三个中,您最好只为更短的代码定义 List

于 2012-05-29T10:13:53.500 回答