ArrayList
java.lang.Object
|—java.util.AbstractCollection<E&
|—|—java.util.AbstractList<E&
|—|—|—java.util.ArrayList<E&
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
List 接口的可调整大小的数组实现。 实现所有可选列表操作,并允许所有元素,包括 null。 除了实现 List 接口之外,该类还提供了一些方法来操作内部用于存储列表的数组的大小。 (这个类大致相当于 Vector,只是它是不同步的。)
size、isEmpty、get、set、iterator 和 listIterator 操作在恒定时间内运行。 添加操作在摊销常数时间内运行,即添加 n 个元素需要 O(n) 时间。 所有其他操作都以线性时间运行(粗略地说)。 与 LinkedList 实现相比,常数因子较低。
每个 ArrayList 实例都有一个容量。 容量是用于存储列表中元素的数组的大小。 它总是至少与列表大小一样大。 随着元素被添加到 ArrayList,它的容量会自动增长。 除了添加一个元素具有恒定的摊销时间成本这一事实之外,没有指定增长策略的细节。
应用程序可以在使用 ensureCapacity 操作添加大量元素之前增加 ArrayList 实例的容量。 这可以减少增量重新分配的数量。
请注意,此实现不同步。 如果多个线程同时访问一个 ArrayList 实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。 (结构修改是添加或删除一个或多个元素,或显式调整后备数组大小的任何操作;仅设置元素的值不是结构修改。)这通常通过同步一些自然封装的对象来完成 列表。 如果不存在这样的对象,则应使用 Collections#synchronizedList 方法“包装”该列表。 这最好在创建时完成,以防止对列表的意外不同步访问:
List list = Collections.synchronizedList(new ArrayList(...));
此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间对列表进行结构修改,除了通过迭代器自己的 ListIterator#remove() 或 ListIterator#add(Object) 之外的任何方式方法,迭代器将抛出 ConcurrentModificationException。因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。
请注意,不能保证迭代器的快速失败行为,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。快速失败的迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。
此类是 Java 集合框架的成员。
字段摘要
从类 java.util.AbstractList 继承的字段 |
---|
modCount |
构造函数摘要
构造函数 | 描述 |
---|---|
ArrayList() | 构造一个初始容量为 10 的空列表。 |
ArrayList(int initialCapacity) | 构造一个具有指定初始容量的空列表。 |
ArrayList(Collection<? extends E> c) | 按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表。 |
方法总结
修饰符和类型 | 方法 | 描述 |
---|---|---|
void | add(int index, E element) | 在此列表中的指定位置插入指定元素。 |
boolean | add(E e) | 将指定元素附加到此列表的末尾。 |
boolean | addAll(int index, Collection<? extends E> c) | 将指定集合中的所有元素插入此列表,从指定位置开始。 |
boolean | addAll(Collection<? extends E> c) | 按照指定集合的迭代器返回的顺序,将指定集合中的所有元素附加到此列表的末尾。 |
void | clear() | 从此列表中删除所有元素。 |
Object | clone() | 返回此 ArrayList 实例的浅表副本。 |
boolean | contains(Object o) | 如果此列表包含指定元素,则返回 true。 |
void | ensureCapacity(int minCapacity) | 如有必要,增加此 ArrayList 实例的容量,以确保它至少可以容纳最小容量参数指定的元素数量。 |
void | forEach(Consumer<? super E> action) | 对 Iterable 的每个元素执行给定的操作,直到处理完所有元素或该操作引发异常。 |
E | get(int index) | 返回此列表中指定位置的元素。 |
int | indexOf(Object o) | 返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回 -1。 |
boolean | isEmpty() | 如果此列表不包含任何元素,则返回 true。 |
IteratorE | iterator() | 以正确的顺序返回此列表中元素的迭代器。 |
int | lastIndexOf(Object o) | 返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回 -1。 |
ListIteratorE | listIterator() | 返回此列表中元素的列表迭代器(以正确的顺序)。 |
ListIteratorE | listIterator(int index) | 返回此列表中元素的列表迭代器(以正确的顺序),从列表中的指定位置开始。 |
E | remove(int index) | 移除此列表中指定位置的元素。 |
boolean | remove(Object o) | 从此列表中删除第一次出现的指定元素(如果存在)。 |
boolean | removeAll(Collection<?> c) | 从此列表中删除包含在指定集合中的所有元素。 |
boolean | removeIf(Predicate<? super E> filter) | 删除此集合中满足给定谓词的所有元素。 |
protected void | removeRange(int fromIndex, int toIndex) | 从此列表中删除索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 |
void | replaceAll(UnaryOperatorE operator) | 将此列表的每个元素替换为将运算符应用于该元素的结果。 |
boolean | retainAll(Collection<?> c) | 仅保留此列表中包含在指定集合中的元素。 |
E | set(int index, E element) | 将此列表中指定位置的元素替换为指定元素。 |
int | size() | 返回此列表中的元素数。 |
void | sort(Comparator<? super E> c) | 根据指定 Comparator 产生的顺序对该列表进行排序。 |
SpliteratorE | spliterator() | 在此列表中的元素上创建一个后期绑定和快速失败的拆分器。 |
ListE | subList(int fromIndex, int toIndex) | 返回此列表在指定的 fromIndex(包括)和 toIndex(不包括)之间的部分的视图。 |
Object[] | toArray() | 以正确的顺序(从第一个元素到最后一个元素)返回包含此列表中所有元素的数组。 |
<T> T[] | toArray(T[] a) | 以正确的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组; 返回数组的运行时类型是指定数组的运行时类型。 |
void | trimToSize() | 将此 ArrayList 实例的容量修剪为列表的当前大小。 |
从类 java.util.AbstractCollection 继承的方法 |
---|
containsAll, toString |
从类 java.util.AbstractList 继承的方法 |
---|
equals, hashCode |
从接口 java.util.Collection 继承的方法 |
---|
parallelStream, stream |
从接口 java.util.List 继承的方法 |
---|
containsAll, equals, hashCode |
从类 java.lang.Object 继承的方法 |
---|
finalize, getClass, notify, notifyAll, wait, wait, wait |
构造函数详细信息
ArrayList
public ArrayList(int initialCapacity)
构造一个具有指定初始容量的空列表。
参数:
参数名称 | 参数描述 |
---|---|
initialCapacity | 列表的初始容量 |
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalArgumentException | 如果指定的初始容量为负 |
ArrayList
public ArrayList()
构造一个初始容量为 10 的空列表。
ArrayList
public ArrayList(Collection<? extends E> c)
按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表。
参数:
参数名称 | 参数描述 |
---|---|
c | 将其元素放入此列表的集合 |
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果指定的集合为空 |
方法详情
trimToSize
public void trimToSize()
将此 ArrayList 实例的容量修剪为列表的当前大小。 应用程序可以使用此操作来最小化 ArrayList 实例的存储。
ensureCapacity
public void ensureCapacity(int minCapacity)
如有必要,增加此 ArrayList 实例的容量,以确保它至少可以容纳最小容量参数指定的元素数量。
参数:
参数名称 | 参数描述 |
---|---|
minCapacity | 所需的最小容量 |
size
public int size()
返回此列表中的元素数。
指定者:
接口 CollectionE 中的大小
指定者:
接口 ListE 中的大小
指定者:
AbstractCollectionE 类中的大小
返回:
此列表中的元素数
isEmpty
public boolean isEmpty()
如果此列表不包含任何元素,则返回 true。
指定者:
接口 CollectionE 中的 isEmpty
指定者:
接口 ListE 中的 isEmpty
覆盖:
类 AbstractCollectionE 中的 isEmpty
返回:
如果此列表不包含任何元素,则为 true
contains
public boolean contains(Object o)
如果此列表包含指定元素,则返回 true。 更正式地说,当且仅当此列表包含至少一个元素 e 满足 (o==null ? e==null : o.equals(e)) 时,才返回 true。
指定者:
包含在接口 CollectionE 中
指定者:
包含在接口 ListE 中
覆盖:
包含在类 AbstractCollectionE 中
参数:
参数名称 | 参数描述 |
---|---|
o | 要测试其在此列表中的存在的元素 |
返回:
如果此列表包含指定元素,则为 true
indexOf
public int indexOf(Object o)
返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回 -1。 更正式地说,返回满足 (o==null ? get(i)==null : o.equals(get(i))) 的最低索引 i,如果没有这样的索引,则返回 -1。
指定者:
接口 ListE 中的 indexOf
覆盖:
AbstractListE 类中的 indexOf
参数:
参数名称 | 参数描述 |
---|---|
o | 要搜索的元素 |
返回:
此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则为 -1
lastIndexOf
public int lastIndexOf(Object o)
返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回 -1。 更正式地说,返回满足 (o==null ? get(i)==null : o.equals(get(i))) 的最高索引 i,如果没有这样的索引,则返回 -1。
指定者:
接口 ListE 中的 lastIndexOf
覆盖:
类 AbstractListE 中的 lastIndexOf
参数:
参数名称 | 参数描述 |
---|---|
o | 要搜索的元素 |
返回:
此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则为 -1
clone
public Object clone()
返回此 ArrayList 实例的浅表副本。 (元素本身不会被复制。)
覆盖:
在类 Object 中克隆
返回:
此 ArrayList 实例的克隆
toArray
public Object[] toArray()
以正确的顺序(从第一个元素到最后一个元素)返回包含此列表中所有元素的数组。
返回的数组将是“安全的”,因为此列表不维护对它的引用。 (换句话说,这个方法必须分配一个新数组)。 因此,调用者可以自由修改返回的数组。
此方法充当基于数组和基于集合的 API 之间的桥梁。
指定者:
接口 CollectionE 中的 toArray
指定者:
接口 ListE 中的 toArray
覆盖:
AbstractCollectionE 类中的 toArray
返回:
以正确顺序包含此列表中所有元素的数组
toArray
public <T> T[] toArray(T[] a)
以正确的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组; 返回数组的运行时类型是指定数组的运行时类型。 如果列表适合指定的数组,则在其中返回。 否则,将使用指定数组的运行时类型和此列表的大小分配一个新数组。
如果列表适合指定的数组并有剩余空间(即,数组的元素多于列表),则数组中紧跟集合末尾的元素设置为 null。 (仅当调用者知道列表不包含任何空元素时,这对确定列表的长度很有用。)
指定者:
接口 CollectionE 中的 toArray
指定者:
接口 ListE 中的 toArray
覆盖:
AbstractCollectionE 类中的 toArray
类型参数:
类型参数名称 | 类型参数描述 |
---|---|
T | 包含集合的数组的运行时类型 |
参数:
参数名称 | 参数描述 |
---|---|
a | 存储列表元素的数组(如果它足够大); 否则,将为此目的分配相同运行时类型的新数组。 |
返回:
包含列表元素的数组
Throws:
Throw名称 | Throw描述 |
---|---|
ArrayStoreException | 如果指定数组的运行时类型不是此列表中每个元素的运行时类型的超类型 |
NullPointerException | 如果指定的数组为空 |
get
public E get(int index)
返回此列表中指定位置的元素。
指定者:
进入接口 ListE
指定者:
进入类 AbstractListE
参数:
参数名称 | 参数描述 |
---|---|
index | 要返回的元素的索引 |
返回:
此列表中指定位置的元素
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果索引超出范围 (index < 0 || index >= size()) |
set
public E set(int index, E element)
将此列表中指定位置的元素替换为指定元素。
指定者:
在接口 ListE 中设置
覆盖:
在类 AbstractListE 中设置
参数:
参数名称 | 参数描述 |
---|---|
index | 要替换的元素的索引 |
element | 要存储在指定位置的元素 |
返回:
先前在指定位置的元素
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果索引超出范围 (index < 0 || index >= size()) |
add
public boolean add(E e)
将指定元素附加到此列表的末尾。
指定者:
添加接口CollectionE
指定者:
添加接口ListE
覆盖:
添加类 AbstractListE
参数:
参数名称 | 参数描述 |
---|---|
e | 要附加到此列表的元素 |
返回:
true(由 Collection#add 指定)
add
public void add(int index, E element)
在此列表中的指定位置插入指定元素。 将当前位于该位置的元素(如果有)和任何后续元素向右移动(将其索引加一)。
指定者:
添加接口ListE
覆盖:
添加类 AbstractListE
参数:
参数名称 | 参数描述 |
---|---|
index | 要插入指定元素的索引 |
element | 要插入的元素 |
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果索引超出范围 (index < 0 || index > size()) |
remove
public E remove(int index)
移除此列表中指定位置的元素。 将任何后续元素向左移动(从它们的索引中减去 1)。
指定者:
在接口 ListE 中删除
覆盖:
在类 AbstractListE 中删除
参数:
参数名称 | 参数描述 |
---|---|
index | 要删除的元素的索引 |
返回:
从列表中删除的元素
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果索引超出范围 (index < 0 || index >= size()) |
remove
public boolean remove(Object o)
从此列表中删除第一次出现的指定元素(如果存在)。 如果列表不包含该元素,则它不变。 更正式地说,删除具有最低索引 i 的元素,使得 (o==null ? get(i)==null : o.equals(get(i))) (如果存在这样的元素)。 如果此列表包含指定的元素(或等效地,如果此列表因调用而更改),则返回 true。
指定者:
在接口 CollectionE 中删除
指定者:
在接口 ListE 中删除
覆盖:
在类 AbstractCollectionE 中删除
参数:
参数名称 | 参数描述 |
---|---|
o | 要从此列表中删除的元素(如果存在) |
返回:
如果此列表包含指定元素,则为 true
clear
public void clear()
从此列表中删除所有元素。 此调用返回后,列表将为空。
指定者:
在界面 CollectionE 中清除
指定者:
在接口 ListE 中清除
覆盖:
在类 AbstractListE 中清除
addAll
public boolean addAll(Collection<? extends E> c)
按照指定集合的迭代器返回的顺序,将指定集合中的所有元素附加到此列表的末尾。 如果在操作正在进行时修改了指定的集合,则此操作的行为是未定义的。 (这意味着如果指定的集合是这个列表,并且这个列表是非空的,那么这个调用的行为是未定义的。)
指定者:
接口 CollectionE 中的 addAll
指定者:
接口 ListE 中的 addAll
覆盖:
类 AbstractCollectionE 中的 addAll
参数:
参数名称 | 参数描述 |
---|---|
c | 包含要添加到此列表的元素的集合 |
返回:
如果此列表因调用而更改,则为 true
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果指定的集合为空 |
addAll
public boolean addAll(int index, Collection<? extends E> c)
将指定集合中的所有元素插入此列表,从指定位置开始。 将当前位于该位置的元素(如果有)和任何后续元素向右移动(增加它们的索引)。 新元素将按照指定集合的迭代器返回的顺序出现在列表中。
指定者:
接口 ListE 中的 addAll
覆盖:
类 AbstractListE 中的 addAll
参数:
参数名称 | 参数描述 |
---|---|
index | 插入指定集合中第一个元素的索引 |
c | 包含要添加到此列表的元素的集合 |
返回:
如果此列表因调用而更改,则为 true
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果索引超出范围 (index < 0 || index > size()) |
NullPointerException | 如果指定的集合为空 |
removeRange
protected void removeRange(int fromIndex, int toIndex)
从此列表中删除索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 将任何后续元素向左移动(减少它们的索引)。 此调用通过 (toIndex – fromIndex) 元素缩短列表。 (如果toIndex==fromIndex,则此操作无效。)
覆盖:
AbstractListE 类中的 removeRange
参数:
参数名称 | 参数描述 |
---|---|
fromIndex | 要删除的第一个元素的索引 |
toIndex | 要删除的最后一个元素之后的索引 |
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果 fromIndex 或 toIndex 超出范围 (fromIndex < 0 || fromIndex >= size() || toIndex > size() || toIndex < fromIndex) |
removeAll
public boolean removeAll(Collection<?> c)
从此列表中删除包含在指定集合中的所有元素。
指定者:
接口 CollectionE 中的 removeAll
指定者:
接口 ListE 中的 removeAll
覆盖:
类 AbstractCollectionE 中的 removeAll
参数:
参数名称 | 参数描述 |
---|---|
c | 包含要从此列表中删除的元素的集合 |
返回:
如果此列表因调用而更改,则为 true
Throws:
Throw名称 | Throw描述 |
---|---|
ClassCastException | 如果此列表的某个元素的类与指定的集合不兼容(可选) |
NullPointerException | 如果此列表包含空元素并且指定的集合不允许空元素(可选),或者指定的集合为空 |
retainAll
public boolean retainAll(Collection<?> c)
仅保留此列表中包含在指定集合中的元素。 换句话说,从这个列表中删除所有不包含在指定集合中的元素。
指定者:
接口CollectionE中的retainAll
指定者:
接口 ListE 中的 retainAll
覆盖:
类 AbstractCollectionE 中的 retainAll
参数:
参数名称 | 参数描述 |
---|---|
c | 包含要保留在此列表中的元素的集合 |
返回:
如果此列表因调用而更改,则为 true
Throws:
Throw名称 | Throw描述 |
---|---|
ClassCastException | 如果此列表的某个元素的类与指定的集合不兼容(可选) |
NullPointerException | 如果此列表包含空元素并且指定的集合不允许空元素(可选),或者指定的集合为空 |
listIterator
public ListIteratorE listIterator(int index)
返回此列表中元素的列表迭代器(以正确的顺序),从列表中的指定位置开始。 指定的索引指示初始调用 ListIterator#next 将返回的第一个元素。 对 ListIterator#previous 的初始调用将返回具有指定索引减一的元素。
返回的列表迭代器是快速失败的。
指定者:
接口 ListE 中的 listIterator
覆盖:
AbstractListE 类中的 listIterator
参数:
参数名称 | 参数描述 |
---|---|
index | 要从列表迭代器返回的第一个元素的索引(通过调用 ListIterator#next) |
返回:
此列表中元素的列表迭代器(按正确顺序),从列表中的指定位置开始
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果索引超出范围 (index < 0 || index > size()) |
listIterator
public ListIteratorE listIterator()
返回此列表中元素的列表迭代器(以正确的顺序)。
返回的列表迭代器是快速失败的。
指定者:
接口 ListE 中的 listIterator
覆盖:
AbstractListE 类中的 listIterator
返回:
此列表中元素的列表迭代器(按正确顺序)
iterator
public IteratorE iterator()
以正确的顺序返回此列表中元素的迭代器。
返回的迭代器是快速失败的。
指定者:
接口 CollectionE 中的迭代器
指定者:
接口 IterableE 中的迭代器
指定者:
接口 ListE 中的迭代器
覆盖:
AbstractListE 类中的迭代器
返回:
以正确顺序遍历此列表中的元素的迭代器
subList
public ListE subList(int fromIndex, int toIndex)
返回此列表在指定的 fromIndex(包括)和 toIndex(不包括)之间的部分的视图。 (如果 fromIndex 和 toIndex 相等,则返回列表为空。)返回列表由此列表支持,因此返回列表中的非结构性更改会反映在此列表中,反之亦然。 返回的列表支持所有可选的列表操作。
这种方法消除了显式范围操作的需要(通常存在于数组中的那种)。 通过传递 subList 视图而不是整个列表,任何需要列表的操作都可以用作范围操作。 例如,以下习惯用法从列表中删除一系列元素:
list.subList(from, to).clear();
可以为 indexOf(java.lang.Object) 和 lastIndexOf(java.lang.Object) 构造类似的习语,并且可以将 Collections 类中的所有算法应用于子列表。
如果后备列表(即此列表)以除通过返回列表之外的任何方式进行结构修改,则此方法返回的列表的语义将变为未定义。 (结构修改是改变这个列表的大小,或者以其他方式扰乱它,使得正在进行的迭代可能会产生不正确的结果。)
指定者:
接口 ListE 中的子列表
覆盖:
AbstractListE 类中的子列表
参数:
参数名称 | 参数描述 |
---|---|
fromIndex | subList 的低端点(包括) |
toIndex | subList 的高端(不包括) |
返回:
此列表中指定范围的视图
Throws:
Throw名称 | Throw描述 |
---|---|
IndexOutOfBoundsException | 如果端点索引值超出范围(fromIndex < 0 || toIndex > size) |
IllegalArgumentException | 如果端点索引乱序(fromIndex > toIndex) |
forEach
public void forEach(Consumer<? super E> action)
从接口复制的描述:Iterable
对 Iterable 的每个元素执行给定的操作,直到处理完所有元素或该操作引发异常。 除非实现类另有规定,否则按迭代顺序执行操作(如果指定了迭代顺序)。 操作引发的异常将转发给调用者。
指定者:
接口 IterableE 中的 forEach
参数:
参数名称 | 参数描述 |
---|---|
action | 为每个元素执行的操作 |
spliterator
public SpliteratorE spliterator()
在此列表中的元素上创建一个后期绑定和快速失败的拆分器。
Spliterator 报告 Spliterator#SIZED、Spliterator#SUBSIZED 和 Spliterator#ORDERED。 覆盖实现应记录附加特征值的报告。
指定者:
接口 CollectionE 中的分离器
指定者:
接口 IterableE 中的分离器
指定者:
接口 ListE 中的分离器
返回:
此列表中元素的拆分器
removeIf
public boolean removeIf(Predicate<? super E> filter)
从接口复制的描述:集合
删除此集合中满足给定谓词的所有元素。 在迭代期间或由谓词引发的错误或运行时异常将转发给调用者。
指定者:
接口 CollectionE 中的 removeIf
参数:
参数名称 | 参数描述 |
---|---|
filter | 对于要删除的元素返回 true 的谓词 |
返回:
如果删除了任何元素,则为 true
replaceAll
public void replaceAll(UnaryOperatorE operator)
从接口复制的描述:列表
将此列表的每个元素替换为将运算符应用于该元素的结果。 操作员抛出的错误或运行时异常被转发给调用者。
指定者:
接口 ListE 中的 replaceAll
参数:
参数名称 | 参数描述 |
---|---|
operator | 应用于每个元素的运算符 |
sort
public void sort(Comparator<? super E> c)
从接口复制的描述:列表
根据指定 Comparator 产生的顺序对该列表进行排序。
此列表中的所有元素必须使用指定的比较器进行相互比较(即 c.compare(e1, e2) 不得为列表中的任何元素 e1 和 e2 抛出 ClassCastException)。
如果指定的比较器为空,则此列表中的所有元素都必须实现 Comparable 接口,并且应使用元素的 Comparable。
此列表必须是可修改的,但不需要调整大小。
指定者:
在接口 ListE 中排序
参数:
参数名称 | 参数描述 |
---|---|
c | Comparator 用于比较列表元素。 空值表示应该使用元素的 Comparable |