Implement algorithm to merge playlists

This commit is contained in:
GGAutomaton 2022-04-13 22:46:24 +08:00
parent c34549a47d
commit 270a541a7c
3 changed files with 57 additions and 7 deletions

View file

@ -11,18 +11,62 @@ import java.util.List;
public interface PlaylistLocalItem extends LocalItem {
String getOrderingName();
long getDisplayIndex();
static List<PlaylistLocalItem> merge(
final List<PlaylistMetadataEntry> localPlaylists,
final List<PlaylistRemoteEntity> remotePlaylists) {
// todo: merge algorithm
final List<PlaylistLocalItem> items = new ArrayList<>(
// Merge localPlaylists and remotePlaylists by displayIndex.
// If two items have the same displayIndex, sort them in CASE_INSENSITIVE_ORDER.
// This algorithm is similar to the merge operation in merge sort.
final List<PlaylistLocalItem> result = new ArrayList<>(
localPlaylists.size() + remotePlaylists.size());
items.addAll(localPlaylists);
items.addAll(remotePlaylists);
final List<PlaylistLocalItem> itemsWithSameIndex = new ArrayList<>();
int i = 0;
int j = 0;
while (i < localPlaylists.size()) {
while (j < remotePlaylists.size()) {
if (remotePlaylists.get(j).getDisplayIndex()
<= localPlaylists.get(i).getDisplayIndex()) {
addItem(result, remotePlaylists.get(j), itemsWithSameIndex);
j++;
} else {
break;
}
}
addItem(result, localPlaylists.get(i), itemsWithSameIndex);
i++;
}
addItemsWithSameIndex(result, itemsWithSameIndex);
Collections.sort(items, Comparator.comparing(PlaylistLocalItem::getOrderingName,
// If displayIndex does not match actual index, update displayIndex.
// This may happen when a new list is created with default displayIndex = 0.
// todo: update displayIndex
return result;
}
static void addItem(final List<PlaylistLocalItem> result, final PlaylistLocalItem item,
final List<PlaylistLocalItem> itemsWithSameIndex) {
if (!itemsWithSameIndex.isEmpty()
&& itemsWithSameIndex.get(0).getDisplayIndex() != item.getDisplayIndex()) {
// The new item has a different displayIndex,
// add previous items with same index to the result.
addItemsWithSameIndex(result, itemsWithSameIndex);
itemsWithSameIndex.clear();
}
itemsWithSameIndex.add(item);
}
static void addItemsWithSameIndex(final List<PlaylistLocalItem> result,
final List<PlaylistLocalItem> itemsWithSameIndex) {
if (itemsWithSameIndex.size() > 1) {
Collections.sort(itemsWithSameIndex,
Comparator.comparing(PlaylistLocalItem::getOrderingName,
Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER)));
return items;
}
result.addAll(itemsWithSameIndex);
}
}

View file

@ -39,4 +39,9 @@ public class PlaylistMetadataEntry implements PlaylistLocalItem {
public String getOrderingName() {
return name;
}
@Override
public long getDisplayIndex() {
return displayIndex;
}
}

View file

@ -153,6 +153,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem {
this.uploader = uploader;
}
@Override
public long getDisplayIndex() {
return displayIndex;
}