java设计模式迭代器模式
Iterator design pattern in one of the behavioral pattern. Iterator pattern is used to provide a standard way to traverse through a group of Objects. Iterator pattern is widely used in Java Collection Framework. Iterator interface provides methods for traversing through a collection.
迭代器设计模式中的一种行为模式。 迭代器模式用于提供遍历一组对象的标准方法。 Iterator模式在Java Collection Framework中被广泛使用。 迭代器接口提供了遍历集合的方法。
迭代器设计模式 (Iterator Design Pattern)
According to GoF, iterator design pattern intent is:
根据GoF,迭代器设计模式的意图是:
Provides a way to access the elements of an aggregate object without exposing its underlying represenation.
提供一种在不暴露其基础表示的情况下访问聚合对象的元素的方法。
Iterator pattern is not only about traversing through a collection, we can provide different kind of iterators based on our requirements.
迭代器模式不仅涉及遍历集合,我们还可以根据需求提供不同种类的迭代器。
Iterator design pattern hides the actual implementation of traversal through the collection and client programs just use iterator methods.
迭代器设计模式通过集合隐藏了遍历的实际实现,而客户端程序仅使用迭代器方法。
迭代器模式示例 (Iterator Pattern Example)
Let’s understand iterator pattern with a simple example. Suppose we have a list of Radio channels and the client program want to traverse through them one by one or based on the type of channel. For example some client programs are only interested in English channels and want to process only them, they don’t want to process other types of channels.
让我们用一个简单的例子来了解迭代器模式。 假设我们有一个无线电频道列表,并且客户端程序要一一遍或根据频道类型遍历它们。 例如,某些客户端程序仅对英语频道感兴趣,并且只想处理它们,而不希望处理其他类型的频道。
So we can provide a collection of channels to the client and let them write the logic to traverse through the channels and decide whether to process them. But this solution has lots of issues such as client has to come up with the logic for traversal. We can’t make sure that client logic is correct. Furthermore if the number of client grows then it will become very hard to maintain.
因此,我们可以向客户提供渠道的集合,让他们编写逻辑来遍历渠道并决定是否进行处理。 但是此解决方案存在很多问题,例如客户端必须提出遍历的逻辑。 我们无法确保客户端逻辑正确。 此外,如果客户数量增加,那么将很难维护。
Here we can use Iterator pattern and provide iteration based on type of channel. We should make sure that client program can access the list of channels only through the iterator.
在这里,我们可以使用Iterator模式,并根据通道类型提供迭代。 我们应该确保客户端程序只能通过迭代器访问频道列表。
The first part of implementation is to define the contract for our collection and iterator interfaces.
实现的第一部分是为我们的collection和iterator接口定义协定。
ChannelTypeEnum.java
ChannelTypeEnum.java
package com.journaldev.design.iterator;
public enum ChannelTypeEnum {
ENGLISH, HINDI, FRENCH, ALL;
}
ChannelTypeEnum is java enum that defines all the different types of channels.
ChannelTypeEnum是Java枚举 ,它定义所有不同类型的通道。
Channel.java
Channel.java
package com.journaldev.design.iterator;
public class Channel {
private double frequency;
private ChannelTypeEnum TYPE;
public Channel(double freq, ChannelTypeEnum type){
this.frequency=freq;
this.TYPE=type;
}
public double getFrequency() {
return frequency;
}
public ChannelTypeEnum getTYPE() {
return TYPE;
}
@Override
public String toString(){
return "Frequency="+this.frequency+", Type="+this.TYPE;
}
}
Channel is a simple POJO class that has attributes frequency and channel type.
通道是一个简单的POJO类,具有频率和通道类型属性。
ChannelCollection.java
ChannelCollection.java
package com.journaldev.design.iterator;
public interface ChannelCollection {
public void addChannel(Channel c);
public void removeChannel(Channel c);
public ChannelIterator iterator(ChannelTypeEnum type);
}
ChannelCollection interface defines the contract for our collection class implementation. Notice that there are methods to add and remove a channel but there is no method that returns the list of channels. ChannelCollection has a method that returns the iterator for traversal. ChannelIterator interface defines following methods;
ChannelCollection接口为我们的集合类实现定义合同。 请注意,有一些方法可以添加和删除频道,但是没有方法可以返回频道列表。 ChannelCollection有一个返回迭代器以进行遍历的方法。 ChannelIterator接口定义以下方法;
ChannelIterator.java
ChannelIterator.java
package com.journaldev.design.iterator;
public interface ChannelIterator {
public boolean hasNext();
public Channel next();
}
Now our base interface and core classes are ready, let’s proceed with the implementation of collection class and iterator.
现在我们的基本接口和核心类已经准备好,让我们继续实现collection类和迭代器。
ChannelCollectionImpl.java
ChannelCollectionImpl.java
package com.journaldev.design.iterator;
import java.util.ArrayList;
import java.util.List;
public class ChannelCollectionImpl implements ChannelCollection {
private List<Channel> channelsList;
public ChannelCollectionImpl() {
channelsList = new ArrayList<>();
}
public void addChannel(Channel c) {
this.channelsList.add(c);
}
public void removeChannel(Channel c) {
this.channelsList.remove(c);
}
@Override
public ChannelIterator iterator(ChannelTypeEnum type) {
return new ChannelIteratorImpl(type, this.channelsList);
}
private class ChannelIteratorImpl implements ChannelIterator {
private ChannelTypeEnum type;
private List<Channel> channels;
private int position;
public ChannelIteratorImpl(ChannelTypeEnum ty,
List<Channel> channelsList) {
this.type = ty;
this.channels = channelsList;
}
@Override
public boolean hasNext() {
while (position < channels.size()) {
Channel c = channels.get(position);
if (c.getTYPE().equals(type) || type.equals(ChannelTypeEnum.ALL)) {
return true;
} else
position++;
}
return false;
}
@Override
public Channel next() {
Channel c = channels.get(position);
position++;
return c;
}
}
}
Notice the inner class implementation of iterator interface so that the implementation can’t be used by any other collection. Same approach is followed by collection classes also and all of them have inner class implementation of Iterator interface.
注意迭代器接口的内部类实现,以便任何其他集合都不能使用该实现。 集合类也遵循相同的方法,并且它们都具有Iterator接口的内部类实现。
Let’s write a simple iterator pattern test program to use our collection and iterator to traverse through the collection of channels.
让我们编写一个简单的迭代器模式测试程序,以使用我们的集合和迭代器遍历通道的集合。
IteratorPatternTest.java
IteratorPatternTest.java
package com.journaldev.design.iterator;
public class IteratorPatternTest {
public static void main(String[] args) {
ChannelCollection channels = populateChannels();
ChannelIterator baseIterator = channels.iterator(ChannelTypeEnum.ALL);
while (baseIterator.hasNext()) {
Channel c = baseIterator.next();
System.out.println(c.toString());
}
System.out.println("******");
// Channel Type Iterator
ChannelIterator englishIterator = channels.iterator(ChannelTypeEnum.ENGLISH);
while (englishIterator.hasNext()) {
Channel c = englishIterator.next();
System.out.println(c.toString());
}
}
private static ChannelCollection populateChannels() {
ChannelCollection channels = new ChannelCollectionImpl();
channels.addChannel(new Channel(98.5, ChannelTypeEnum.ENGLISH));
channels.addChannel(new Channel(99.5, ChannelTypeEnum.HINDI));
channels.addChannel(new Channel(100.5, ChannelTypeEnum.FRENCH));
channels.addChannel(new Channel(101.5, ChannelTypeEnum.ENGLISH));
channels.addChannel(new Channel(102.5, ChannelTypeEnum.HINDI));
channels.addChannel(new Channel(103.5, ChannelTypeEnum.FRENCH));
channels.addChannel(new Channel(104.5, ChannelTypeEnum.ENGLISH));
channels.addChannel(new Channel(105.5, ChannelTypeEnum.HINDI));
channels.addChannel(new Channel(106.5, ChannelTypeEnum.FRENCH));
return channels;
}
}
When I run above program, it produces following output;
当我运行上面的程序时,它会产生以下输出;
Frequency=98.5, Type=ENGLISH
Frequency=99.5, Type=HINDI
Frequency=100.5, Type=FRENCH
Frequency=101.5, Type=ENGLISH
Frequency=102.5, Type=HINDI
Frequency=103.5, Type=FRENCH
Frequency=104.5, Type=ENGLISH
Frequency=105.5, Type=HINDI
Frequency=106.5, Type=FRENCH
******
Frequency=98.5, Type=ENGLISH
Frequency=101.5, Type=ENGLISH
Frequency=104.5, Type=ENGLISH
迭代器设计模式要点 (Iterator Design Pattern Important Points)
- Iterator pattern is useful when you want to provide a standard way to iterate over a collection and hide the implementation logic from client program. 当您想提供一种标准方法来迭代集合并从客户端程序中隐藏实现逻辑时,迭代器模式非常有用。
- The logic for iteration is embedded in the collection itself and it helps client program to iterate over them easily. 迭代逻辑嵌入在集合本身中,它可以帮助客户端程序轻松地对其进行迭代。
JDK中的迭代器设计模式 (Iterator Design Pattern in JDK)
We all know that Collection framework Iterator is the best example of iterator pattern implementation but do you know that java.util.Scanner
class also Implements Iterator interface. Read this post to learn about Java Scanner Class.
我们都知道Collection框架Iterator是迭代器模式实现的最佳示例,但是您知道java.util.Scanner
类也实现Iterator接口。 阅读这篇文章以了解Java扫描程序类 。
That’s all for iterator design pattern, I hope it’s helpful and easy to understand.
这就是迭代器设计模式的全部,我希望它是有用的并且易于理解。
翻译自: https://www.journaldev.com/1716/iterator-design-pattern-java
java设计模式迭代器模式