在 Java 中,我们总是可以使用数组来存储对象引用。然后我们有一个 ArrayList 或 HashTable 可以自动扩展来存储对象。但是有谁知道拥有一个可自动扩展的对象引用数组的原生方式?
编辑:我的意思是我想知道 Java API 是否有一些类能够存储对对象的引用(但不存储像 XXXList 或 HashTable 这样的实际对象)以及自动扩展的能力。
在 Java 中,我们总是可以使用数组来存储对象引用。然后我们有一个 ArrayList 或 HashTable 可以自动扩展来存储对象。但是有谁知道拥有一个可自动扩展的对象引用数组的原生方式?
编辑:我的意思是我想知道 Java API 是否有一些类能够存储对对象的引用(但不存储像 XXXList 或 HashTable 这样的实际对象)以及自动扩展的能力。
根据定义,Java 数组是固定大小的。如果您需要自动增长,请使用 XXXList 类。
编辑 - 问题已经澄清了一点
当我第一次开始学习 Java(来自 C 和 C++ 背景)时,这可能是最先让我绊倒的事情之一。希望我能有所启发。
与 C++ 不同,Java 中的对象数组不存储对象。它们存储对象引用。
在 C++ 中,如果您声明类似以下内容:
String myStrings[10];
你会得到 10 个 String 对象。此时,执行类似 println(myStrings[5].length); 之类的操作是完全合法的。- 你会得到 '0' - String 的默认构造函数会创建一个长度为 0 的空字符串。
在 Java 中,当你构造一个新数组时,你会得到一个可以容纳 10 个字符串引用的空容器。所以调用:
String[] myStrings = new String[10];
println(myStringsp[5].length);
会抛出空指针异常,因为您实际上还没有将 String 引用放入数组中。
如果您来自 C++ 背景,请将 new String[10] 视为等同于 C++ 中的 new (String *)[10]。
因此,考虑到这一点,应该很清楚为什么 ArrayList是自动扩展对象数组的解决方案(事实上,ArrayList 是使用简单数组实现的,内置增长算法,可以根据需要分配新的扩展数组,并且将旧内容复制到新内容)。
在实践中,实际上我们使用数组的情况相对较少。如果您正在编写一个容器(类似于 ArrayList 或 BTree),那么它们很有用,或者如果您正在执行大量低级字节操作 - 但在大多数开发发生的级别上,使用 Collections 类之一是目前首选的技术。
所有实现 Collection 的类都是可扩展的并且只存储引用:你不存储对象,你在一些数据空间中创建它们并且只操作对它们的引用,直到它们超出范围而不引用它们。
您可以将一个对象的引用放在两个或多个集合中。这就是您可以对哈希表进行排序的方式......
“本地”方式是什么意思?如果你想要一个可扩展的 f 对象列表,那么你可以使用 ArrayList。使用 List 集合,您可以使用 get(index) 方法,该方法允许您通过索引访问列表中的对象,这为您提供了与数组类似的功能。在内部,ArrayList 是用一个数组实现的,ArrayList 会自动为您处理扩展它。
直接来自sun 网页上的Array Java 教程:
-> 数组是一个容器对象,它包含固定数量的单一类型的值。
因为数组的大小是在创建的时候就声明的,所以后面其实是没办法扩展的。声明一个特定大小的数组的全部目的是只分配程序执行时可能使用的内存。您可以做的是声明第二个数组,它是一个基于原始大小的函数,将所有原始元素复制到其中,然后添加必要的新元素(尽管这不是很“自动”:)) . 否则,正如您和其他一些人所提到的,列表集合是最有效的方法。
在 Java 中,所有对象变量都是引用。所以
Foo myFoo = new Foo();
Foo anotherFoo = myFoo;
意味着两个变量都引用同一个对象,而不是两个单独的副本。同样,当您将对象放入 aCollection
时,您只是存储对该对象的引用。因此使用ArrayList
或类似方法是拥有自动扩展存储的正确方法。
我知道没有一流的语言结构可以做到这一点,如果那是您正在寻找的。
它不是很有效,但如果你只是追加到一个数组,你可以使用Apache Commons ArrayUtils.add()。它返回原始数组的副本,其中包含附加元素。
如果您可以用 javascript 编写代码,是的,您可以这样做。javascript数组是稀疏数组。它将以您想要的任何方式扩展。
你可以写
一[0] = 4;
一个[1000] = 434;
a[888] = "一个字符串";