“核心技术:集合”的版本间差异
跳到导航
跳到搜索
(→迭代器) |
(→泛型使用方法) |
||
第113行: | 第113行: | ||
=== 泛型使用方法 === | === 泛型使用方法 === | ||
* 由于Collection 与Iterator 都是'''泛型接口''',可以编写操作任何集合类型的实用方法。 | |||
* Java 类库提供了一个类AbstractCollection,它将基础方法size和iterator抽象化了,但是提供了例行方法。 | |||
*: 所以,一个具体的集合类可以扩展AbstractCollection 类了(实际上也是这样的) | |||
*: 然而,这种“伴随类”并不是最好的方式,在原接口中将方法定义为“默认方法”会更好。 | |||
==== java.util.Collection<E> ==== | |||
# Iterator < E> iterator() | |||
#: 返回一个用于访问集合中每个元素的迭代器。 | |||
# int size() | |||
#: 返回当前存储在集合中的元素个数。 | |||
# boolean isEmpty() | |||
#: 如果集合中没有元素, 返回true。 | |||
# boolean contains(Object obj) | |||
#: 如果集合中包含了一个与obj 相等的对象, 返回true。 | |||
# boolean containsAl 1(Collection<?> other) | |||
#: 如果这个集合包含other 集合中的所有元素, 返回trueo | |||
# boolean add(Object element) | |||
#: 将一个元素添加到集合中。如果由于这个调用改变了集合,返回true。 | |||
# boolean addAl1(Col1ection<? extends E> other) | |||
#: 将other 集合中的所有元素添加到这个集合。如果由于这个调用改变了集合,返回true。 | |||
# boolean remove(Object obj) | |||
#: 从这个集合中删除等于obj 的对象。如果有匹配的对象被删除, 返回true。 | |||
# boolean removeAl 1(Col 1ection<?> other) | |||
#: 从这个集合中删除other 集合中存在的所有元素。如果由于这个调用改变了集合,返回true。 | |||
# default boolean removelf(Predicate<? super E> filter)8 | |||
#: 从这个集合删除filter 返回true 的所有元素。如果由于这个调用改变了集合,则返回true。 | |||
# void clear() | |||
#: 从这个集合中删除所有的元素。 | |||
# boolean retainAl1(Collection<?> other) | |||
#: 从这个集合中删除所有与other 集合中的元素不同的元素。如果由于这个调用改变了集合, 返回true。 | |||
# Object[]toArray() | |||
#: 返回这个集合的对象数组。 | |||
# <T> T[]toArray(T[]arrayToFi11) | |||
#: 返回这个集合的对象数组。如果arrayToFill 足够大,就将集合中的元素填入这个数组中。剩余空间填补null; 否则,分配一个新数组,其成员类型与arrayToFill的成员类型相同,其长度等于集合的大小,并填充集合元素。 | |||
==== java.util.Iterator<E> ==== | |||
# boolean hasNext() | |||
#: 如果存在可访问的元素, 返回true。 | |||
# E next() | |||
#: 返回将要访问的下一个对象。如果已经到达了集合的尾部, 将拋出一个NoSuchElementException。 | |||
# void remove( ) | |||
#: 删除上次访问的对象。这个方法必须紧跟在访问一个元素之后执行。如果上次访问之后,集合已经发生了变化, 这个方法将抛出一个IllegalStateException。 | |||
=== 集合框架中的接口 === | === 集合框架中的接口 === |
2020年10月18日 (日) 18:24的版本
Java 集合框架
将集合的接口与实现分离
与现代的数据结构类库的常见情况一样, Java 集合类库也将接口( interface ) 与实现( implementation) 分离。
以队列为例:
队列接口的最简形式可能类似下面这样:
public interface Queue<E> // a simplified form of the interface in the standard library
{
void add(E element) ;
E remove();
int size();
}
而,队列通常有两种实现方式:
- 一种是使用循环数组;
- 另一种是使用链表;
Colloction 接口
在Java 类库中,集合类的基本接口是Collection 接口。这个接口有两个基本方法
public interface Collection<b
{
boolean add(E element);
Iterator<E> iteratorQ;
...
}
- add 方法用于向集合中添加元素。如果添加元素确实改变了集合就返回true, 如果集合没有发生变化就返回false;
- iterator 方法用于返回一个实现了Iterator 接口的对象;
- 可以使用这个迭代器对象依次访问集合中的元素。
迭代器
Iterator 接口包含4 个方法:
public interface Iterator<E>
{
E next(); // 逐个访问集合中的每个元素(如果到达了集合的末尾将抛出一个NoSuchElementException)
boolean hasNext(); // 遍历时判断是否还有下一个元素
void remove(); //
default void forEachRemaining(Consumer<? super E> action) ; // 对迭代器的每一个元素调用action(Consumer是一个函数式接口,所以可用lambda表达式)
}
如果想要査看集合中的所有元素,就请求一个迭代器,并在hasNext 返回true 时反复地调用next 方法。例如:
Collection<String> c = . . .;
Iterator<String> iter = c.iteratorO;
while (iter.hasNextO)
{
String element = iter.next0;
// do something with element
}
用“ foreach” 循环可以更加简练地表示同样的循环操作:
for (String element : c)
{
// do something with element
}
- 编译器简单地将“for each” 循环翻译为带有迭代器的循环,“for each”循环可以与任何实现了Iterable 接口的对象一起工作;
- Collection 接口扩展了(而非继承)Iterable 接口。因此,对于标准类库中的任何集合都可以使用“for each” 循环。
- 在Java SE 8 中,甚至不用写循环。可以调用forEachRemaining方法并提供 lambda 表达式(它会处理一个元素)。
- 将对迭代器的每一个元素调用这个lambda 表达式,直到再没有元素为止。
i terator.forEachRemai ni ng(el ement -> do something with element);
- 元素被访问的顺序取决于集合类型。
- 如对 ArrayList:迭代器将从索引 0 开始,每次迭代索引值加 1;
- 然而,如对 HashSet 迭代:每个元素将会按照某种随机的次序出现。(能够遍历到集合中的所有元素,但却无法预知元素被访问的次序)
关于迭代器的位置
应该将Java 迭代器认为是位于两个元素之间(而非指向一个元素)。当调用next 时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。
- Iterator 接口的 remove 方法将会删除上次调用next 方法时返回的元素;
如:
- 删除集合首个元素:
Iterator<String> it = c.iterator(); it.nextO; // skip over the first element it.remove(); // now remove it
- 删除两个相邻的元素:
it.remove(); it.next0; it.remove(); // 而非 // it.remove(); // it.remove();
泛型使用方法
- 由于Collection 与Iterator 都是泛型接口,可以编写操作任何集合类型的实用方法。
- Java 类库提供了一个类AbstractCollection,它将基础方法size和iterator抽象化了,但是提供了例行方法。
- 所以,一个具体的集合类可以扩展AbstractCollection 类了(实际上也是这样的)
- 然而,这种“伴随类”并不是最好的方式,在原接口中将方法定义为“默认方法”会更好。
java.util.Collection<E>
- Iterator < E> iterator()
- 返回一个用于访问集合中每个元素的迭代器。
- int size()
- 返回当前存储在集合中的元素个数。
- boolean isEmpty()
- 如果集合中没有元素, 返回true。
- boolean contains(Object obj)
- 如果集合中包含了一个与obj 相等的对象, 返回true。
- boolean containsAl 1(Collection<?> other)
- 如果这个集合包含other 集合中的所有元素, 返回trueo
- boolean add(Object element)
- 将一个元素添加到集合中。如果由于这个调用改变了集合,返回true。
- boolean addAl1(Col1ection<? extends E> other)
- 将other 集合中的所有元素添加到这个集合。如果由于这个调用改变了集合,返回true。
- boolean remove(Object obj)
- 从这个集合中删除等于obj 的对象。如果有匹配的对象被删除, 返回true。
- boolean removeAl 1(Col 1ection<?> other)
- 从这个集合中删除other 集合中存在的所有元素。如果由于这个调用改变了集合,返回true。
- default boolean removelf(Predicate<? super E> filter)8
- 从这个集合删除filter 返回true 的所有元素。如果由于这个调用改变了集合,则返回true。
- void clear()
- 从这个集合中删除所有的元素。
- boolean retainAl1(Collection<?> other)
- 从这个集合中删除所有与other 集合中的元素不同的元素。如果由于这个调用改变了集合, 返回true。
- Object[]toArray()
- 返回这个集合的对象数组。
- <T> T[]toArray(T[]arrayToFi11)
- 返回这个集合的对象数组。如果arrayToFill 足够大,就将集合中的元素填入这个数组中。剩余空间填补null; 否则,分配一个新数组,其成员类型与arrayToFill的成员类型相同,其长度等于集合的大小,并填充集合元素。
java.util.Iterator<E>
- boolean hasNext()
- 如果存在可访问的元素, 返回true。
- E next()
- 返回将要访问的下一个对象。如果已经到达了集合的尾部, 将拋出一个NoSuchElementException。
- void remove( )
- 删除上次访问的对象。这个方法必须紧跟在访问一个元素之后执行。如果上次访问之后,集合已经发生了变化, 这个方法将抛出一个IllegalStateException。