Nia*_*all 7 java recursion android
我正在尝试为类的层次结构编写迭代器,这些类共同构成了歌曲的组成部分.所有类都是抽象MusicComponent基类的实现并继承了一个getChildren()函数.抽象MusicTime子类都知道实际的音符/和弦玩,和所有的实施方式(例如八分音符,四分音符)回报null了getChildren().
其他组件MusicComponent一次保存MusicTimes例如条形的集合,并且Section保持该组合MusicComponents.Song拥有Sections构成歌曲的歌曲,例如诗歌,合唱,具有不同节奏/时间签名的部分.
我需要的是一个迭代器,将通过所有迭代Sections的Song,那么所有MusicComponents的Section,只有当它找到一个MusicTime传人,演奏的音符为基础的音符类型的时间长度,时间签名和节奏包含其的Section.
对不起,如果信息太多,但是我能解释我正在尝试做什么的唯一方法.那么我是否需要使用堆栈来处理这个问题,MusicComponents我已经访问过哪些记录,或者只是使用递归来实现这一点?
您可以编写一个迭代器来“连接”其子迭代器,甚至是懒惰的。然后调用next()aSong的迭代器将向下钻取Section和MusicComponent迭代器,最后交付下一个MusicTime。
番石榴使这变得容易。制作MusicComponent并Iterable<MusicTime>实施iterator()为:
@Override
public Iterator<MusicTime> iterator() {
return Iterables.concat(getChildren()).iterator();
}
Run Code Online (Sandbox Code Playgroud)
由于所有子级都是MusicComponents 并因此实现Iterable<MusicTime>它们自己,Song因此 的迭代器将是迭代器的串联Section,而迭代器本身也是MusicTime迭代器的串联。
最后一个迭代器是一个特例。迭代MusicTime器应该只返回自身一次:
@Override
public Iterator<MusicTime> iterator() {
return Iterators.singletonIterator(this);
}
Run Code Online (Sandbox Code Playgroud)
或者,Section的迭代器可以替换为:
@Override
public Iterator<MusicTime> iterator() {
return getChildren().iterator();
}
Run Code Online (Sandbox Code Playgroud)
有了这个,迭代就变得很简单:
for (MusicTime time : song) {
player.play(time);
}
Run Code Online (Sandbox Code Playgroud)
您现在可以执行任何类型的操作(播放、计算总持续时间……),而无需重新实现递归。
虽然您的问题有其他解决方案,但这一切都取决于设计选择。例如,您可以拥有一个play方法,并MusicComponent通过调用其所有子级来实现该方法。这是一个简单的递归实现,但是您必须对要添加的所有操作重复递归(例如,SongSectionplayMusicComponentplaygetTotalDuration、...)重复递归。
如果您需要更大的灵活性,您可以使用访问者设计模式并使您的播放操作成为访问者(例如PlayVisitor)。这样做的优点是您可以决定从访问者内部控制迭代顺序,但会增加添加新MusicComponent实现的难度。
| 归档时间: |
|
| 查看次数: |
5034 次 |
| 最近记录: |