“核心技术:集合”的版本间差异

来自Wikioe
跳到导航 跳到搜索
无编辑摘要
第3行: 第3行:
== Java 集合框架 ==
== Java 集合框架 ==


=== 将集合的接口与实现分离 ===


与现代的数据结构类库的常见情况一样, Java 集合类库也将接口( interface ) 与实现( implementation) 分离。<br/>
以队列为例:
: [[File:队列.png|600px]]
队列接口的最简形式可能类似下面这样:
<syntaxhighlight lang="java">
public interface Queue<E> // a simplified form of the interface in the standard library
{
  void add(E element) ;
  E remove();
  int size();
}
</syntaxhighlight>
而,队列通常有两种实现方式:
# 一种是使用循环数组;
# 另一种是使用链表;
: [[File:队列的实现.png|600px]]
=== Colloction 接口 ===
在Java 类库中,集合类的基本接口是Collection 接口。这个接口有两个基本方法
<syntaxhighlight lang="java">
public interface Collection<b
{
  boolean add(E element);
  Iterator<E> iteratorQ;
  ...
}
</syntaxhighlight>
# add 方法用于向集合中添加元素。如果添加元素确实改变了集合就返回true, 如果集合没有发生变化就返回false;
# iterator 方法用于返回一个实现了Iterator 接口的对象;
#: 可以使用这个迭代器对象依次访问集合中的元素。
=== 迭代器 ===
Iterator 接口包含4 个方法:
<syntaxhighlight lang="java">
public interface Iterator<E>
{
E next();          // 逐个访问集合中的每个元素(如果到达了集合的末尾将抛出一个NoSuchElementException)
boolean hasNext();    // 遍历时判断是否还有下一个元素
void remove();      //
default void forEachRemaining(Consumer<? super E> action) ;   // 对迭代器的每一个元素调用action(Consumer是一个函数式接口,所以可用lambda表达式)
}
</syntaxhighlight>
如果想要査看集合中的所有元素,就请求一个迭代器,并在hasNext 返回true 时反复地调用next 方法。例如:
<syntaxhighlight lang="java">
Collection<String> c = . . .;
Iterator<String> iter = c.iteratorO;
while (iter.hasNextO)
{
  String element = iter.next0;
  // do something with element
}
</syntaxhighlight>
用“ foreach” 循环可以更加简练地表示同样的循环操作:
<syntaxhighlight lang="java">
for (String element : c)
{
  // do something with element
}
</syntaxhighlight>
* '''编译器简单地将“for each” 循环翻译为带有迭代器的循环''',“for each”循环可以与任何实现了Iterable 接口的对象一起工作;
*: Collection 接口扩展了(而非继承)Iterable 接口。因此,对于标准类库中的任何集合都可以使用“for each” 循环。
* 在Java SE 8 中,甚至不用写循环。可以调用'''forEachRemaining'''方法并提供 lambda 表达式(它会处理一个元素)。
*: 将对迭代器的每一个元素调用这个lambda 表达式,直到再没有元素为止。
*: <syntaxhighlight lang="java">
i terator.forEachRemai ni ng(el ement -> do something with element);
</syntaxhighlight>
* '''元素被访问的顺序取决于集合类型'''。
*: 如对 ArrayList:迭代器将从索引 0 开始,每次迭代索引值加 1;
*: 然而,如对 HashSet 迭代:每个元素将会按照某种随机的次序出现。(能够遍历到集合中的所有元素,但却无法预知元素被访问的次序)
==== 关于迭代器的位置 ====
'''应该将Java 迭代器认为是位于两个元素之间(而非指向一个元素)'''。当调用next 时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。<br/>
[[File:迭代器的位置.png|400px]]
* Iterator 接口的 '''remove 方法将会删除上次调用next 方法时返回的元素''';
如:
# 删除集合首个元素:
#: <syntaxhighlight lang="java">
Iterator<String> it = c.iterator();
it.nextO;        // skip over the first element
it.remove();    // now remove it
</syntaxhighlight>
# 删除两个相邻的元素:
#: <syntaxhighlight lang="java">
it.remove();
it.next0;
it.remove();
// 而非
// it.remove();
// it.remove();
</syntaxhighlight>
'''[[关于Iterable与Iterator的那些事]]'''
=== 泛型使用方法 ===
=== 集合框架中的接口 ===


== 具体的集合 ==
== 具体的集合 ==

2020年10月18日 (日) 17:48的版本


Java 集合框架

将集合的接口与实现分离

与现代的数据结构类库的常见情况一样, Java 集合类库也将接口( interface ) 与实现( implementation) 分离。


以队列为例:

队列.png

队列接口的最简形式可能类似下面这样:

public interface Queue<E> // a simplified form of the interface in the standard library
{
   void add(E element) ;
   E remove();
   int size()
}

而,队列通常有两种实现方式:

  1. 一种是使用循环数组;
  2. 另一种是使用链表;
队列的实现.png


Colloction 接口

在Java 类库中,集合类的基本接口是Collection 接口。这个接口有两个基本方法

public interface Collection<b
{
   boolean add(E element);
   Iterator<E> iteratorQ;
   ...
}
  1. add 方法用于向集合中添加元素。如果添加元素确实改变了集合就返回true, 如果集合没有发生变化就返回false;
  2. 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 时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。
迭代器的位置.png


  • Iterator 接口的 remove 方法将会删除上次调用next 方法时返回的元素


如:

  1. 删除集合首个元素:
    Iterator<String> it = c.iterator();
    it.nextO;        // skip over the first element
    it.remove();     // now remove it
    
  2. 删除两个相邻的元素:
    it.remove();
    it.next0
    it.remove();
    
    // 而非
    // it.remove();
    // it.remove();
    


关于Iterable与Iterator的那些事

泛型使用方法

集合框架中的接口

具体的集合

映射

视图与包装器

算法

遗留的集合