|
11 | 11 | public interface PlaylistLocalItem extends LocalItem { |
12 | 12 | String getOrderingName(); |
13 | 13 |
|
| 14 | + long getDisplayIndex(); |
| 15 | + |
14 | 16 | static List<PlaylistLocalItem> merge( |
15 | 17 | final List<PlaylistMetadataEntry> localPlaylists, |
16 | 18 | final List<PlaylistRemoteEntity> remotePlaylists) { |
17 | | - // todo: merge algorithm |
18 | | - final List<PlaylistLocalItem> items = new ArrayList<>( |
| 19 | + |
| 20 | + // Merge localPlaylists and remotePlaylists by displayIndex. |
| 21 | + // If two items have the same displayIndex, sort them in CASE_INSENSITIVE_ORDER. |
| 22 | + // This algorithm is similar to the merge operation in merge sort. |
| 23 | + |
| 24 | + final List<PlaylistLocalItem> result = new ArrayList<>( |
19 | 25 | localPlaylists.size() + remotePlaylists.size()); |
20 | | - items.addAll(localPlaylists); |
21 | | - items.addAll(remotePlaylists); |
| 26 | + final List<PlaylistLocalItem> itemsWithSameIndex = new ArrayList<>(); |
| 27 | + int i = 0; |
| 28 | + int j = 0; |
| 29 | + while (i < localPlaylists.size()) { |
| 30 | + while (j < remotePlaylists.size()) { |
| 31 | + if (remotePlaylists.get(j).getDisplayIndex() |
| 32 | + <= localPlaylists.get(i).getDisplayIndex()) { |
| 33 | + addItem(result, remotePlaylists.get(j), itemsWithSameIndex); |
| 34 | + j++; |
| 35 | + } else { |
| 36 | + break; |
| 37 | + } |
| 38 | + } |
| 39 | + addItem(result, localPlaylists.get(i), itemsWithSameIndex); |
| 40 | + i++; |
| 41 | + } |
| 42 | + addItemsWithSameIndex(result, itemsWithSameIndex); |
| 43 | + |
| 44 | + // If displayIndex does not match actual index, update displayIndex. |
| 45 | + // This may happen when a new list is created with default displayIndex = 0. |
| 46 | + // todo: update displayIndex |
22 | 47 |
|
23 | | - Collections.sort(items, Comparator.comparing(PlaylistLocalItem::getOrderingName, |
24 | | - Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER))); |
| 48 | + return result; |
| 49 | + } |
| 50 | + |
| 51 | + static void addItem(final List<PlaylistLocalItem> result, final PlaylistLocalItem item, |
| 52 | + final List<PlaylistLocalItem> itemsWithSameIndex) { |
| 53 | + if (!itemsWithSameIndex.isEmpty() |
| 54 | + && itemsWithSameIndex.get(0).getDisplayIndex() != item.getDisplayIndex()) { |
| 55 | + // The new item has a different displayIndex, |
| 56 | + // add previous items with same index to the result. |
| 57 | + addItemsWithSameIndex(result, itemsWithSameIndex); |
| 58 | + itemsWithSameIndex.clear(); |
| 59 | + } |
| 60 | + itemsWithSameIndex.add(item); |
| 61 | + } |
25 | 62 |
|
26 | | - return items; |
| 63 | + static void addItemsWithSameIndex(final List<PlaylistLocalItem> result, |
| 64 | + final List<PlaylistLocalItem> itemsWithSameIndex) { |
| 65 | + if (itemsWithSameIndex.size() > 1) { |
| 66 | + Collections.sort(itemsWithSameIndex, |
| 67 | + Comparator.comparing(PlaylistLocalItem::getOrderingName, |
| 68 | + Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER))); |
| 69 | + } |
| 70 | + result.addAll(itemsWithSameIndex); |
27 | 71 | } |
28 | 72 | } |
0 commit comments