对象+列表中的对象列表?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象+列表中的对象列表?相关的知识,希望对你有一定的参考价值。
我有一个有趣且麻烦的任务要解决。我需要创建一个包含歌曲和其他歌曲子播放列表的播放列表(某种列表)...每个播放列表都有播放模式(随机,序列等)是否可以创建这样的播放列表?我考虑破解子播放列表并将其中的附加歌曲添加到主播放列表中,或者为添加到主播放列表的每首歌创建一个子播放列表(我真的不喜欢这个想法)不知何故它绕过了问题但是有必要保持每个播放列表的播放模式......
例如:
主播放列表(序列palymode)具有:(1)歌曲1-1 /(2)子播放列表(歌曲2-1,歌曲-2-2,歌曲2-3)与随机播放模式/(3)song1-2
期望的结果:(1)song1-1 /(2)song2-3(开始随机子播放列表)/(3)song2-1 /(4)song2-2 /(5)song1-2 /
我该怎么办呢?
由于我怀疑这是某种功课,我只会为您提供部分实施,因此您可以了解如何继续。
创建一个抽象类PlaylistElement
,后来可以是Song
或另一个Playlist
。
abstract class PlaylistElement {
public abstract List<Song> printSongs();
}
实现扩展Playlist
的类PlaylistElement
。
class Playlist extends PlaylistElement {
private List<PlaylistElement> elements;
private PlaybackMode playbackMode;
@Override
public List<Song> printSongs() {
if(this.playbackMode == PlaybackMode.RANDOM) {
List<Song> songs = new ArrayList<>();
List<PlaylistElement> shuffleElements = new ArrayList<>();
//Add all PlaylistElements from elements into shuffleElements
//and shuffle the shuffleElements collection
//insert your songs into the songs collection here by sequentially
//going through your
//PlaylistElements and inserting the result of their printSongs()
//implementation (e.g. in a for-loop)
return songs;
}
else if(this.playbackMode == PlaybackMode.SEQUENTIAL) {
//you can do this on your own
}
return null;
}
}
实现扩展Song
的类PlaylistElement
。
class Song extends PlaylistElement {
private String title;
private String artist;
.
.
.
@Override
public List<Song> printSongs() {
//return a List with only this Song instance inside
return Arrays.asList(new Song[] { this });
}
}
为播放列表播放模式创建枚举。
enum PlaybackMode {
SEQUENTIAL, RANDOM;
}
希望这能给你一个大致的想法!为简洁省略了Getters / Setters和其他重要部分。
已经有了一些答案,我答应提供一个示例实现。我们开始有一个通用接口Playable
,它是为复合设计模式实现的类。
public interface Playable {
String getSongName();
}
接下来,Song
类代表一首歌。
public class Song implements Playable {
private String name;
public Song(String name) {
this.name = name;
}
@Override
public String getSongName() {
return name;
}
}
为Playlist
类准备一个enum来代表不同的游戏模式。
public enum PlayingMode {
SEQUENCE, RANDOM
}
现在,最后是播放列表。
public class Playlist implements Playable {
private String name;
private List<Playable> playables = new ArrayList<>();
private PlayingMode mode;
private Playable currentItem;
private List<Playable> next = new ArrayList<>();
public Playlist(String name, PlayingMode mode) {
this.name = name;
this.mode = mode;
}
@Override
public String getSongName() {
if (playables.isEmpty()) {
return null;
}
if (currentItem == null) {
// initialize the playing songs
next.addAll(playables);
if (mode == PlayingMode.RANDOM) {
Collections.shuffle(next);
}
currentItem = next.get(0);
} else {
// if we have a playlist, play its songs first
if (currentItem instanceof Playlist) {
String candidate = currentItem.getSongName();
if (candidate != null) {
return candidate;
}
}
int index = next.indexOf(currentItem);
index++;
if (index < next.size()) {
currentItem = next.get(index);
} else {
currentItem = null;
}
}
return currentItem != null ? currentItem.getSongName() : null;
}
private void addToNext(Playable playable) {
if (currentItem == null) {
return;
}
// if the playlist is playing, add it to those list as well
if (mode == PlayingMode.SEQUENCE) {
next.add(playable);
} else if (mode == PlayingMode.RANDOM) {
int currentIndex = next.indexOf(currentItem);
int random = ThreadLocalRandom.current().nextInt(currentIndex, next.size());
next.add(random, playable);
}
}
public void addPlayable(Playable playable) {
Objects.requireNonNull(playable);
playables.add(playable);
addToNext(playable);
}
}
一些例子:
public static void main(String[] args) {
Song song1 = new Song("Song 1");
Song song2 = new Song("Song 2");
Playlist subPlaylist1 = new Playlist("Playlist 1", PlayingMode.RANDOM);
subPlaylist1.addPlayable(new Song("Song A"));
subPlaylist1.addPlayable(new Song("Song B"));
subPlaylist1.addPlayable(new Song("Song C"));
Song song3 = new Song("Song 3");
Playlist main = new Playlist("Main", PlayingMode.SEQUENCE);
main.addPlayable(song1);
main.addPlayable(song2);
main.addPlayable(subPlaylist1);
main.addPlayable(song3);
String songName = main.getSongName();
while (songName != null) {
System.out.println("Current song is: " + songName);
songName = main.getSongName();
}
}
可以给出输出:
Current song is: Song 1
Current song is: Song 2
Current song is: Song B
Current song is: Song A
Current song is: Song C
Current song is: Song 3
您还可以在播放时添加歌曲:
while (songName != null) {
System.out.println("Current song is: " + songName);
songName = main.getSongName();
// add songs while playing
if ("Song A".equals(songName)) {
subPlaylist1.addPlayable(new Song("Song D"));
subPlaylist1.addPlayable(new Song("Song E"));
subPlaylist1.addPlayable(new Song("Song F"));
}
}
这可能导致:
Current song is: Song 1
Current song is: Song 2
Current song is: Song B
Current song is: Song A
Current song is: Song E
Current song is: Song D
Current song is: Song F
Current song is: Song C
Current song is: Song 3
最后的一些说明:
getIndex
方法确实具有O(n)的最坏情况运行时,如果播放列表中有许多歌曲,则可能是一个问题。像Collection
或Set
这样更快的Map
会提供更好的性能,但实现起来有点复杂。- 这些类已被简化,这意味着为简洁起见,省略了一些getter和setter以及equals和hashCode。
方法1:创建一个名为播放列表和播放列表项的类,它可以保存songIds列表,可以保存来自不同播放列表或歌曲ID的歌曲集。
class PlayList{
List<PlayListItem> playlistItems;
}
class PlayListItem{
List<String> songIds;
}
如果您想要识别通过特定子播放列表添加的歌曲集,这将有用。然而,与方法2相比,这种方法使迭代变得困难
方法2:此处在播放列表项中避免列表,因此在显示播放列表时的迭代很简单。但是,必须计算通过特定子播放列表添加的songIds列表。
class PlayList{
List<PlayListItem> playlistItems;
}
class PlayListItem{
String songId;
String referencePlayListId;
}
以上是关于对象+列表中的对象列表?的主要内容,如果未能解决你的问题,请参考以下文章