目的: Array.length
为我们提供了初始化为数组的存储空间。但是想从初始化的总存储中找出存储在数组中的非空元素的数量。我知道有很多方法是可行的,但这里的问题与我使用的方法有关。
因为 ArrayList
有一个 size()
方法,它为我们提供了实际存储元素的计数,而不考虑初始化的总存储量。
所以,我想到了将数组转换为 ArrayList
并找出大小。因此我使用了 Arrays.asList(a).size()
如下所示:
public class Driver {
public static void main(String []args)
{
int a[] = new int[10];
a[0]=30;
a[1]=100;
a[2]=33;
System.out.println((Arrays.asList(a)).size() );
}
奇怪的是,不管 a[0]
、a[1]
、a[2]
,它返回的结果都是 1。
如果我们使用 ArrayList
而不是 Array 执行相同的步骤,则会得到结果 3:
{
List<Integer> temp = new ArrayList<Integer>(20);
System.out.println(temp.size());
temp.add(20);
temp.add(40);
System.out.println(temp.size());
}
结果是 0 2
。
问题: 是否应该同意 Arrays
实用程序的 asList
API 有问题,例如错误或限制?
备注:
查看内部实现,我了解到 asList
调用了 ArrayList
的构造函数:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
.....
}
它再次调用集合的 toArray
。但是不确定为什么我们得到的答案是 1,因为 elementData.length
应该存储在大小值 10
中?
最佳答案
您在这里试图以某种方式将三个截然不同的概念等同起来。
首先,列表或数组中有 null
元素。 null
是一个完全有效的值。它与未初始化不同。事实上,任何非基本类型的数组都默认显式初始化为 null
。
然后列表中有未使用的元素。当你这样做的时候
ArrayList<Integer> a = new ArrayList<>(20);
a.add(null);
您将有一个大小为 1 的 List
。null
是一个完全有效的引用,可以粘贴在列表中,容量与大小无关。您传递给构造函数的 20 只是一个提示,在您将 20 个实际元素插入列表之前不要重新分配内存。这 19 个其他元素不是 null
。它们根本不存在。
第三,原始数组的问题。当您创建原始数组时,它将具有固定长度并且每个元素都包含一个有效值。默认情况下,数组被清零为 false
、0
、0L
、0.0f
、0.0
,或任何适合该类型的内容。您的代码创建了一个包含三个非零元素和七个零的数组。基元不是引用,因此永远不能为 null
。即使他们可以,从 10 个元素的数组创建一个 List
也会得到 10 的大小。
您创建 ArrayList
的尝试绝不等同于应用 Arrays.asList()
,即使那是可行的。创建一个列表并向其中添加三个元素将生成一个大小为三的列表。最重要的是,请记住 List
可以仅 保存引用,在您的情况下是装箱类型 Integer
。 Integer
引用可以是 null
并且仍然是有效的列表项,但不能拆箱为原始值。
最后,您不能使用 asList
将基元数组转换为列表。 . asList
接受可变参数,而不是单个列表,这就是为什么您总是以一个元素列表结尾的原因。这里的问题实际上是你有一个基元列表:一个引用数组可以很好地扩展。 Java 8 中的替代方案是
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());
注意显式装箱操作。您的列表的大小仍然是 10,而不是 3。
关于java - 查找大小,即存储在 Java 数组中的非空元素的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52197208/