Объект + Список объектов в списке? - PullRequest
0 голосов
/ 03 февраля 2019

У меня есть интересная и неприятная задача, которую нужно решить.Мне нужно создать список воспроизведения (какой-то список), который содержит песни и другие вспомогательные списки песен ... Каждый список воспроизведения имеет режим воспроизведения (случайный, последовательный и т. Д.). Можно ли создать такой список воспроизведения?Я думал о том, чтобы взламывать суб-плейлисты и добавлять из них дополнительные песни в основной плейлист или создавать суб-плейлист для каждой песни, которая добавляется в основной плейлист (мне не очень нравится эта идея). Однако каким-то образом это решает проблему.необходимо оставаться в режиме воспроизведения каждого списка воспроизведения ...

Например:

Основной список воспроизведения (palymode sequence) имеет: (1) song1-1 / (2) суб-список воспроизведения (song2-1, song2-2, song-2-3) со случайным режимом воспроизведения / (3) song1-2

Желаемый результат: (1) song1-1 / (2) song2-3 (запуск произвольного подплейлиста)/ (3) song2-1 / (4) song2-2 / (5) song1-2 /

как мне подойти к этому?

Ответы [ 3 ]

0 голосов
/ 03 февраля 2019

Поскольку я подозреваю, что это своего рода домашнее задание, я предоставлю вам только частичную реализацию, поэтому вы получите представление о том, как действовать.

Создайте абстрактный класс 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;
}

Надеюсь, это даст вам общее представление!Геттеры / сеттеры и другие важные детали для краткости опущены.

0 голосов
/ 03 февраля 2019

Хотя уже есть некоторые ответы, я обещал предоставить пример реализации.Начнем с того, что у нас есть общий интерфейс 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 перечисление для представления различий режимов воспроизведения.

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, дадут лучшую производительность, но реализация будет немного более сложной.
  • Классы были упрощены, что означает некоторые getters и сеттеры , а также равно и hashCode опущены для краткости.
0 голосов
/ 03 февраля 2019

Подход 1: Создайте класс с именем playlist и элемент списка воспроизведения, который может содержать список songIds, который может содержать набор песен из разных плейлистов или идентификаторов песен.

class PlayList{
  List<PlayListItem> playlistItems;
}

class PlayListItem{
  List<String> songIds;
}

ThisПомогает, если конкретный, если вы хотите идентифицировать набор песен, добавленных через определенный подплейлист.Однако этот подход делает итерацию немного трудной по сравнению с подходом 2

Подход 2: Здесь список избегается в элементе списка воспроизведения, поэтому итерация при отображении списка воспроизведения проста.Однако для идентификации списка songIds, который был добавлен с помощью specificSubPlaylist, необходимо вычислить.

class PlayList{
  List<PlayListItem> playlistItems;
}
class PlayListItem{
  String songId;
  String referencePlayListId;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...