我知道您可以在实例化期间初始化数组,如下所示:
有没有办法用数组列表做同样的事情?还是必须用EDOCX1[0]单独添加内容?
arrays.aslist可以在以下方面提供帮助:
1
| new ArrayList <Integer >(Arrays. asList(1, 2, 3, 5, 8, 13, 21)); |
- 值得一提的是,除非你严格需要一个ArrayList,否则最好使用Arrays#asList返回的List。
- @Maerics,也值得一提的是,Arrays.asList()返回一个不可修改的集合。:)
- 它将引发编译错误"类型数组中的方法aslist(object[])不适用于参数(int,int,int,int,int,int)"。
- 实际实现应为"new arraylist(arrays.aslist(new object[]1,2,3,5,8,13,21));"
- @RK:哪个编译器?我的Eclipse编译得很好…
- @梅里顿:我已经设置了编译器级别,JRE指向1.5…
- @ RK:在我的Eclipse上,它仍然用Java 5遵照JRE 6编译。既然方法签名自JRE 5以来没有改变,我怀疑JRE的重要性。总之,当我写这个答案的时候,Java 5已经结束了。(你不是真的还在用吗?)
- 由Arrays.asList()返回的列表不可修改,@kocko。它的大小是固定的,但您可以更改引用以指向完全不同的对象,如Arrays.asList(...).set(0,new String("new string"))。此代码将起作用,并将列表的第一个元素设置为值为"new string"的字符串对象。事实上,它会写入本机数组!绝对不可更改。
- 为什么人们在他们的帖子中从来没有提到正确的导入/包含/要求声明?
- 因为一个配置良好的IDE将为您编写导入,只要有一个匹配的类,这里就是这样。
- @Konstantinyovkov…完全在列表对象的契约中
- 工作得很好!
对。
1 2 3 4
| new ArrayList<String>(){{
add("A");
add("B");
}} |
这实际上是在创建一个从ArrayList派生的类(大括号的外部集执行此操作),然后声明一个静态初始化器(大括号的内部集)。这实际上是包含类的一个内部类,因此它将有一个隐式的this指针。这不是问题,除非您希望序列化它,或者您希望外部类被垃圾收集。
我理解Java 7将提供额外的语言构造来精确地做您想要的。
编辑:最近的Java版本为创建这样的集合提供了更多可用的功能,并且值得在上面进行调查(在这些版本之前提供的时间)
- 可能是因为人们不知道这是可能的。这实际上是我初始化映射和其他更复杂集合的常用方法,但对于列表,我更喜欢array.aslist。
- 我不是投反对票,但我认为这是对匿名班级的一种非常恶劣的虐待。至少你不想把它当作一个特殊的功能来传递…
- 不好,因为它创建了一个匿名类。
- 我不相信创建一个匿名类本身就是不好的。不过,你应该意识到这一点。
- 我猜它会一直被否决,因为它做的正是OP想要避免的:对每个元素使用add()。
- 小心,解决方案可能导致内存泄漏
- 我会考虑向下投票,因为创建一个类,只是为了初始化一个对象,会让我觉得杀伤力太大。但我不太擅长Java,知道这是不是一件坏事。也许在一个大型程序中创建数千个不必要的类被认为是好的Java编码?如果有很多元素的话,它也非常冗长。与其他建议的答案相比,这种方法有什么优势吗?
- 它可能会被否决,因为它只适用于最终的价值观。我同意你的解决方案确实能解决问题,但你知道有些人在StackOverflow上。
- 它可能被否决了,因为使用此解决方案的大多数用户可能不会阅读/理解解释。至关重要的是,任何一个真正使用它的人,都要完全理解他们在做什么以及它是如何工作的。
- 虽然这看起来不错,但这是一个非常糟糕的主意,这将生成不必要的类对象,这些对象将立即需要进行垃圾收集。在您的代码中包含这一点很难诊断将来的内存问题,只需要一点语法上的甜头。
- 虽然这种初始化有已知的缺点,但我会质疑你的断言。内存问题,特别是考虑到上面的注释和有限的场景
- 似乎@brianagenew在另一个so答案中进一步讨论了这一点。???
这里是你能得到的最接近的:
1
| ArrayList <String > list = new ArrayList(Arrays. asList("Ryan", "Julie", "Bob")); |
您可以更简单地使用:
1
| List <String > list = Arrays. asList("Ryan", "Julie", "Bob") |
查看arrays.aslist的源代码,它构造一个arraylist,但默认情况下是强制转换为list。所以您可以这样做(但对于新的JDK不可靠):
1
| ArrayList <String > list = (ArrayList <String >)Arrays. asList("Ryan", "Julie", "Bob") |
- 由aslist构造的arraylist不是java.util.arraylist,只共享相同的内容。实际上,它不能是,因为as list的返回值被指定为固定大小的列表,但是arraylist必须是可变大小的。
- 我接受纠正。我对消息来源的理解不够深入。
1
| Arrays. asList("Ryan", "Julie", "Bob"); |
在Java中,没有列表的文字语法,所以必须这样做。
如果你有很多元素,这有点冗长,但是你可以:
使用groovy或类似的东西
使用array.aslist(array)
2看起来像:
但这会导致一些不必要的对象创建。
选择的答案是:ArrayList(Arrays.asList(1,2,3,5,8,13,21));。
但是,在创建最终数组之前,了解所选答案在内部多次复制元素是很重要的,并且有一种方法可以减少某些冗余。
让我们从了解正在发生的事情开始:
首先,元素被复制到静态工厂Arrays.asList(T...)创建的Arrays.ArrayList中。
尽管具有相同的简单类名,但这不会产生与java.lang.ArrayList相同的类。它不实现像remove(int)这样的方法,尽管它有一个列表接口。如果调用这些方法,它将抛出一个UnspportedMethodException。但是如果你只需要一个固定大小的列表,你可以停在这里。
接下来,在1中构造的Arrays.ArrayList被传递给构造函数ArrayList<>(Collection),在这里调用collection.toArray()方法来克隆它。
1 2 3 4
| public ArrayList(Collection <? extends E > collection ) {
......
Object[] a = collection. toArray();
} |
接下来,构造函数决定是采用克隆的数组,还是再次复制它以删除子类类型。由于Arrays.asList(T...)在内部使用类型为t的数组(与我们作为参数传递的数组相同),因此构造函数总是拒绝使用克隆,除非t是纯对象。(例如,字符串、整数等都会再次被复制,因为它们会扩展对象)。
1 2 3 4 5 6 7 8 9
| if (a. getClass() != Object[]. class) {
//Arrays.asList(T...) is always true here
//when T subclasses object
Object[] newArray = new Object[a. length];
System. arraycopy(a, 0, newArray, 0, a. length);
a = newArray ;
}
array = a ;
size = a. length; |
因此,我们的数据被复制了3x,只是为了显式地初始化arraylist。如果强制Arrays.asList(T...)构造一个object[]数组,我们可以把它降到2X,这样arraylist以后可以采用它,具体操作如下:
1
| (List <Integer >)(List <?>) new ArrayList <>(Arrays. asList((Object) 1, 2 , 3, 4, 5)); |
或者只是在创建之后添加元素可能仍然是最有效的。
这个怎么样。
1 2
| ArrayList <String > names = new ArrayList <String >();
Collections. addAll(names, "Ryan", "Julie", "Bob"); |
这就是如何使用OP4J Java库的FLUENT接口完成的(1.1)。10年12月发布):。-
1
| List<String> names = Op.onListFor("Ryan","Julie","Bob").get(); |
这是一个非常酷的图书馆,可以节省你一吨时间。