删除包含在另一个数组中的 id 数组

Remove an array of ids contained in another array

如果我有一个 Track 对象数组:

Track[] tracks;

其中每个曲目都有许多字段,其中包括一个字符串 trackId:

public class Track{

    private String trackId;


    private String artistId;
}

然后我有

String trackIdsToRemove[];

我想删除轨道列表中对象中的 trackIdsToRemove[] 中的 ID。

除了迭代之外,还有什么奇特的方法可以做到这一点吗?也许用番石榴?还是 RxJava?

您不能从数组中删除。您可以从列表中删除。将您的数组更改为列表并按此方式执行:

public void remove(String trackIdsToRemove[], List<Track> tracks) {
    for(String str: trackIdsToRemove) {
        tracks.remove(tracks.indexOf(str));
    }
}

无论您将使用什么技巧/库,后端每次都是相同的,您需要找到要删除的元素,然后继续实际删除它。

但是您可以做一些小优化,首先采用最佳数据结构。如果您要经常播放 add/remove 曲目,也许您应该使用列表而不是数组。
然后你也可以按顺序插入你的曲目,这样当你需要找到要删除的曲目时你可以进行二进制搜索。在最坏的情况下,二进制搜索需要 O(log(n)) 才能找到一条轨道,而普通搜索需要 O(n)

有用 link : http://bigocheatsheet.com/#data-structures

您可以使用 ArrayList:

ArrayList array = new ArrayList();
//add elements to array -> array.add(object1);
ArrayList arrayToRemove = new ArrayList();
//add elements to array to remove -> array.add(object1);
for(Object obj : arrayToRemove){
   array.remove(obj);
}

为此,如果您使用自己的对象,则需要覆盖下一个对象函数 equalshashCode,这是此线程中的示例:

  • ArrayList's custom Contains method

如果您使用的是 java 8 和 Guava:

Set<String> toRemove = Sets.newHashSet(trackIdsToRemove);
tracks = Arrays.stream(tracks)
    .filter(t -> !toRemove.contains(t.trackId))
    .toArray(Track[]::new);

我不确定数组中的 "removing" 是什么意思:您根本无法做到这一点,充其量您可以设置为空单元格内容或以某种方式将其标记为 invalid/free .

如果你的数组是按id排序的,你可以对你想要的id进行二分查找"remove"以获得更好的性能:假设N是集合的大小,M是移除集合,那么正常的迭代是 O(n*m),而通过二进制搜索你可以下降到 O(log(n)*m)

一般来说,即使您有一个库,它也会在幕后对这些数据结构执行此操作。

正如其他人指出的那样,如果您需要支持删除,最好使用不同的结构:如果您有 ID,则表明您的项目是唯一的,因此 Set 可能是理想的,否则 List 应该可以,或者一个 Map Obj -> Int 来实现一个 multi-set.

假设您可以更改代码以使用更理想的结构,您可以执行类似 (Java8):

Set<Track> tracks;
Set<String> idsToRemove;
//Note: this has O(n*m) performance, though you could try using .parallelstream() instead of .stream()
Set<Track> remainingOnes = tracks.stream().filter(x -> !idsToRemove.contains(x.id)).collect(Collectors.toSet());