我正在编写一个程序,它接受 400 个类型long
,并将根据运行时的条件修改其中一些,我想知道是否使用ArrayList<Long>
或long[]
.
哪个会更快使用?我正在考虑使用long[]
,因为大小是固定的。
我正在编写一个程序,它接受 400 个类型long
,并将根据运行时的条件修改其中一些,我想知道是否使用ArrayList<Long>
或long[]
.
哪个会更快使用?我正在考虑使用long[]
,因为大小是固定的。
当大小固定时,long[]
速度会更快,但它允许的 API 可维护性较差,因为它不实现List
接口。
注意 along[]
更快有两个原因:
long
s 而不是 box object Long
s(也可以实现更好的缓存性能,因为long
s 是连续分配的,并且Long
s 不能保证)尽管如此,为了更简单的可维护性 - 我会使用List<Long>
, 除非性能在程序的这一部分非常关键。
如果你经常在一个紧密的循环中使用这个集合——并且你的分析器说它确实是一个瓶颈——那么我会切换到一个更有效的long[]
.
就速度而言,400 个项目的列表几乎无关紧要。如果您需要动态增加列表,ArrayList<Long>
那就更好了;如果大小是固定的,long[]
可能会更好(并且速度会更快,尽管在大多数情况下您可能不会注意到差异)。
其他答案中没有提到的几件事:
泛型集合实际上是Object
s 的集合,或者更好地说,这就是 Java 编译器将对其进行的处理。这段时间long[]
将永远保持现状。
第一个要点的结果是,如果您做某事最终将其他内容Long
放入您的集合中,在某些情况下编译器会允许它通过(因为 Java 类型系统不健全,例如,它允许您upcast 然后重新转换为完全不同的类型)。
这两者的一个更普遍的结果是 Java 泛型是半生不熟的,在一些不那么琐碎的情况下,例如反射、序列化等,可能会让您“吃惊”。事实上,使用普通数组比使用泛型更安全。
package tld.example;
import java.util.List;
import java.util.ArrayList;
class Example {
static void testArray(long[] longs) {
System.out.println("testArray");
}
static void testGeneric(List<Long> longs) {
System.out.println("testGeneric");
}
@SuppressWarnings("unchecked")
public static void main(String... arguments) {
List<Long> fakeLongs = new ArrayList<Long>();
List<Object> mischiefManaged = (List<Object>)(Object)fakeLongs;
mischiefManaged.add(new Object());
// this call succeeds and prints the value.
// we could sneak in a wrong type into this function
// and it remained unnoticed
testGeneric(fakeLongs);
long[] realLongs = new long[1];
// this will fail because it is not possible to perform this cast
// despite the compiler thinks it is.
Object[] forgedLongs = (Object[])(Object)realLongs;
forgedLongs[0] = new Object();
testArray(realLongs);
}
}
这个例子有点做作,因为很难想出一个简短的令人信服的例子,但相信我,在不那么琐碎的情况下,当你必须使用反射和不安全的强制转换时,这是很有可能的。
现在,您必须考虑,除了合理之外,还有一个传统。每个社区都有一套它的习俗和传统。有很多肤浅的信念,例如这里所说的那些。当有人声称实现List
API 是无条件的善,如果这没有发生,那么它一定是坏的......这不仅仅是一种主流观点,这是绝大多数 Java 程序员所相信的。毕竟,它没有没那么重要,而 Java,作为一门语言还有很多其他的缺点......所以,如果你想确保你的工作面试或只是避免与其他 Java 程序员发生冲突,那么无论出于何种原因,请使用 Java 泛型. 但是,如果您不喜欢它-好吧,也许只是使用其他语言;)
long[] 既快得多,又占用更少的内存。阅读“Effective Java”第 49 条:“Prefer primitive types to boxed primitives”
我认为使用 ArrayList 更好,因为它更容易长期维护。将来,如果您的数组大小增加到超过 400,那么维护 long[] 会产生很多开销,而 ArrayList 会动态增长,因此您无需担心大小增加。
此外,ArrayList 以比静态数组 (long[]) 更好的方式处理元素的删除,因为它们会自动重新组织元素,以便它们仍然显示为有序元素。静态数组在这方面更糟糕。
为什么不使用适用于原始类型的众多列表实现之一呢?例如TLongArrayList。它可以像 Javas List 一样使用,但基于 long[] 数组。所以你有双方的优势。
HPPC 简要概述了一些库:https ://github.com/carrotsearch/hppc/blob/master/ALTERNATIVES.txt