gpt4 book ai didi

java - 创建递归迭代器

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:05:38 26 4
gpt4 key购买 nike

我正在尝试为共同构成歌曲组件的类层次结构编写一个迭代器。所有类都是抽象 MusicComponent 的实现基类并继承一个getChildren()功能。文摘MusicTime子类知道要演奏的实际音符/和弦,并且它的所有实现(例如四分音符、四分音符)都返回 null对于 getChildren() .

其他组件是MusicComponent其中包含 MusicTimes 的集合例如一次一个酒吧,Section其中包含 MusicComponents . Song持有Sections组成这首歌,例如主歌、副歌、具有不同节奏/拍号的部分。

我需要的是一个遍历所有 Sections 的迭代器在Song , 然后都是 MusicComponentsSection并且只有当它找到 MusicTime 时后代,根据其音符类型以及包含 Section 的拍号和节奏播放音符的时间长度.

抱歉,如果信息太多,但这是我可以解释我正在尝试做的事情的唯一方式。所以我需要用一个堆栈来处理这个,记录哪个MusicComponents我已经访问过或者有没有办法只使用递归来做到这一点?

最佳答案

您可以编写一个迭代器,它“串联”其子级的迭代器,甚至是惰性的。打电话next()Song 上的迭代器然后将向下钻取 SectionMusicComponent迭代器并最终交付下一个 MusicTime .

Guava使这变得容易。制作MusicComponent一个Iterable<MusicTime>并实现 iterator()作为:

@Override
public Iterator<MusicTime> iterator() {
return Iterables.concat(getChildren()).iterator();
}

因为所有 child 都是MusicComponent s 并因此实现 Iterable<MusicTime>他们自己,Song的迭代器将是 Section 的串联迭代器,它们本身是 MusicTime 的串联迭代器。

最后一个迭代器是一个特例。 MusicTime迭代器应该只返回一次:<​​/p>

@Override
public Iterator<MusicTime> iterator() {
return Iterators.singletonIterator(this);
}

或者,Section的迭代器可以替换为:

@Override
public Iterator<MusicTime> iterator() {
return getChildren().iterator();
}

有了这个,迭代变得很容易:

for (MusicTime time : song) {
player.play(time);
}

您现在可以执行任何类型的操作(播放、计算总持续时间……)而无需重新实现递归。

尽管您的问题有多种替代解决方案,但这全都取决于设计选择。例如,您可以有一个 play MusicComponent 上的方法哪个SongSection将通过调用 play 来实现在他们所有的 child 身上。这是一个简单的递归实现,但您必须对要在 MusicComponent 上添加的所有操作重复递归。 (例如 playgetTotalDuration ……)。

如果您需要更大的灵 active ,可以使用 Visitor design pattern并使您的播放操作成为访问者(例如 PlayVisitor )。这样做的好处是您可以决定从访问者内部控制迭代顺序,但会增加新的 MusicComponent 的难度。实现。

关于java - 创建递归迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21708867/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com