在java中,用null填充ArrayList的最快方法是什么?
我想要一个由n组整数组成的列表,最初这个列表应该用null填充。 许多集合将在稍后初始化,有些将保持为空 我尝试了不同的方法来实现这一点,其中一些方法包括:在java中,用null填充ArrayList的最快方法是什么?,java,performance,arraylist,Java,Performance,Arraylist,我想要一个由n组整数组成的列表,最初这个列表应该用null填充。 许多集合将在稍后初始化,有些将保持为空 我尝试了不同的方法来实现这一点,其中一些方法包括: List<HashSet<Integer>> List_of_Sets = Arrays.asList(new HashSet[n]); ^以上代码来自Ross Drew对的回答,如果调整大小对您不重要,那么实现您自己的列表可能会很快。它也可能是马车。与Java的列表相比,至少基准测试是有趣的。您可能会看到一个奇怪
List<HashSet<Integer>> List_of_Sets = Arrays.asList(new HashSet[n]);
^以上代码来自Ross Drew对的回答,如果调整大小对您不重要,那么实现您自己的列表可能会很快。它也可能是马车。与Java的列表相比,至少基准测试是有趣的。您可能会看到一个奇怪的效果,即JIT可能会更快地优化标准列表,因为Java的标准库可以在内部使用它们 这是我的尝试,尽管我建议你不要使用它。改用标准列表实现
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
Set<Integer>[] arr = new Set[100_000]; // all set to null by default.
List<Set<Integer>> myList = new ArrayBackedList<>(arr);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class ArrayBackedList<T> extends AbstractList<T> {
private final T[] arr;
ArrayBackedList(T[] arr) {
this.arr = arr;
}
@Override
public T get(int index) {
return arr[index];
}
@Override
public int size() {
return arr.length;
}
@Override
public T set(int index, T value) {
T result = arr[index];
arr[index] = value;
return result;
}
}
import java.util.*;
公共类FastListOfNullsDemo{
公共静态void main(字符串[]args){
Set[]arr=new Set[100_000];//默认情况下,所有设置均为null。
列表myList=新的ArrayBackedList(arr);
myList.set(3,新树集());
myList.get(3)、add(5);
myList.get(3)、add(4);
myList.get(3)、add(3);
myList.get(3)、add(2);
myList.get(3)、add(1);
//让我们打印一些,因为100000是很多!
对于(int i=0;i<10;i++){
System.out.println(myList.get(i));
}
}
}
类ArrayBackedList扩展了AbstractList{
私人终审法院【】arr;
ArrayBackedList(T[]arr){
this.arr=arr;
}
@凌驾
公共T获取(整数索引){
返回arr[索引];
}
@凌驾
公共整数大小(){
返回arr.length;
}
@凌驾
公共T集(整数索引,T值){
T结果=arr[指数];
arr[指数]=数值;
返回结果;
}
}
另一种可能是实现一个总是空的、固定大小的列表。使用该选项初始化ArrayList。我不能保证它很快,但你可以试试
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
List<Set<Integer>> allNull = new NullList<>(100_000);
List<Set<Integer>> myList = new ArrayList<>(allNull);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
System.out.println(myList.size());
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class NullList<T> extends AbstractList<T> {
private int count;
NullList(int count) {
this.count = count;
}
@Override
public T get(int index) {
return null;
}
@Override
public int size() {
return count;
}
}
import java.util.*;
公共类FastListOfNullsDemo{
公共静态void main(字符串[]args){
List allNull=新的空列表(100_000);
List myList=new ArrayList(allNull);
myList.set(3,新树集());
myList.get(3)、add(5);
myList.get(3)、add(4);
myList.get(3)、add(3);
myList.get(3)、add(2);
myList.get(3)、add(1);
System.out.println(myList.size());
//让我们打印一些,因为100000是很多!
对于(int i=0;i<10;i++){
System.out.println(myList.get(i));
}
}
}
类NullList扩展了AbstractList{
私人整数计数;
空列表(整数计数){
this.count=计数;
}
@凌驾
公共T获取(整数索引){
返回null;
}
@凌驾
公共整数大小(){
返回计数;
}
}
有没有更快的方法
据我所知,没有。当然,没有简单的方法可以更快
基于它的工作原理,我认为(但我还没有测试过)Arrays.asList(newhashset[n])应该是最快的解决方案
可以实现一个自定义的列表
实现,它类似于数组列表
,但预先初始化为Nnull
值。但是在引擎盖下,初始化将与List
实现中发生的情况几乎相同,而asList
将返回该实现。所以我怀疑任何性能改进是否会有意义。。。或者值得付出努力
若您想确定这一点,可以编写各种选项的基准测试。然而,我认为在这种情况下,这不是正确的方法
相反,我建议您对整个应用程序进行基准测试和评测,以确定此列表中的操作是否是真正的性能热点
- 如果它不是一个热点,我的建议是只使用
方法,把时间花在更重要的事情上Arrays.asList
列表
;i、 e.使用位置get
和set
操作,不使用更改列表大小的操作。如果是这样的话,那么使用真实数组应该更有效。它节省了内存,避免了一定程度的间接寻址和(可能的)一些边界检查
不这样做的一个原因是,如果需要将数组传递给其他需要列表的代码
Arrays.asList
版本应该稍微快一点。3) 这是“过早优化”吗?最后,如果速度对您来说真的很重要,您可以用数组替换ArrayList
。这将更快地创建和访问/更新。(在某些情况下只是有点不方便。)据我所知,您将不会利用列表
API添加和删除列表元素的功能….Collections.fill()
对空列表没有任何作用,因此如果您对它感到满意,那就有点令人费解了。有Collections.nCopies()
可以与null
一起使用。我只想List\u of_set=array.asList(新的HashSet[n])
和move ony您还可以编写一个原生方法。谢谢!我最终使用了n个哈希集的数组,因此我将按照您的建议而不使用它。为了将来读者的利益,我对这个问题进行了编辑,使之更具一般性。
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
Set<Integer>[] arr = new Set[100_000]; // all set to null by default.
List<Set<Integer>> myList = new ArrayBackedList<>(arr);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class ArrayBackedList<T> extends AbstractList<T> {
private final T[] arr;
ArrayBackedList(T[] arr) {
this.arr = arr;
}
@Override
public T get(int index) {
return arr[index];
}
@Override
public int size() {
return arr.length;
}
@Override
public T set(int index, T value) {
T result = arr[index];
arr[index] = value;
return result;
}
}
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
List<Set<Integer>> allNull = new NullList<>(100_000);
List<Set<Integer>> myList = new ArrayList<>(allNull);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
System.out.println(myList.size());
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class NullList<T> extends AbstractList<T> {
private int count;
NullList(int count) {
this.count = count;
}
@Override
public T get(int index) {
return null;
}
@Override
public int size() {
return count;
}
}