Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 删除另一个数组中包含的ID数组_Java_Arrays_Optimization_Guava_Rx Java - Fatal编程技术网

Java 删除另一个数组中包含的ID数组

Java 删除另一个数组中包含的ID数组,java,arrays,optimization,guava,rx-java,Java,Arrays,Optimization,Guava,Rx Java,如果我有一个轨迹对象数组: Track[] tracks; 其中每个轨迹都有许多字段,其中包括字符串trackId: public class Track{ private String trackId; private String artistId; } 那我有 String trackIdsToRemove[]; 我想删除trackIdsToRemove[]中的ID,这些ID位于列表轨迹内的对象中 除了迭代之外,还有什么更奇特的方法吗?也许加番石榴?或RxJav

如果我有一个轨迹对象数组:

Track[] tracks;
其中每个轨迹都有许多字段,其中包括字符串trackId:

public class Track{

    private String trackId;


    private String artistId;
}
那我有

String trackIdsToRemove[];
我想删除trackIdsToRemove[]中的ID,这些ID位于列表轨迹内的对象中


除了迭代之外,还有什么更奇特的方法吗?也许加番石榴?或RxJava?

无法从阵列中删除。您可以从列表中删除。将阵列更改为“列表”,然后按以下方式操作:

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

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

但是您可以做一些小的优化,首先采用最好的数据结构。如果要经常添加/删除曲目,可能应该使用列表而不是数组。 然后你还可以按顺序插入你的曲目,这样你就可以在需要查找要删除的曲目时进行二进制搜索。在最坏的情况下,二进制搜索需要Ologn来查找轨迹,而普通搜索则需要Ologn


有用链接:

您可以使用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);
}
为此,如果您正在使用自己的对象,则需要重写下一个对象函数equals和hashCode,以下是此线程的示例:


如果您使用的是java 8和番石榴:

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

我不确定你从数组中删除是什么意思:你不能这么做,充其量你可以将单元格内容设置为空或以某种方式将其标记为无效/免费

如果数组是按id排序的,则可以对要删除的id进行二进制搜索,以获得更好的性能:假设N是集合的大小,M是删除集合的大小,则正常的迭代是在*M上,而通过二进制搜索,可以得到Ologn*M

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

正如其他人所指出的,如果您需要支持删除,最好使用不同的结构:给定您的ID,这表明您的项目是唯一的,因此集合可能是理想的,否则应该使用列表,或者使用Map Obj->Int来实现多集合

假设您可以更改代码以使用更理想的结构,您可以执行类似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());

如果您提供的是infos,则不会。如果主数组按trackId排序,则可以对它们进行二进制搜索。此外,您不能真正从数组中删除,最多可以将单元格的内容设置为null。如果确实必须按列表进行,则可以使用TrackIDStoreRemove as list并执行removeAll。但请注意,trackToRemove是ID的集合,而不是Track对象的集合,因此您需要相应地调整代码:因为现在它不会编译bc类型,因此不兼容removeAll的参数是list类型的集合。事实并非如此。如果我传递一个字符串数组来删除所有曲目列表,它不会删除所有曲目。请在投票前搜索你的答案。这正是我说的:如果你有一组曲目,你可以使用remove或removeAll,但是你有一个字符串id的集合,所以你不能同时使用它们:你的indexOf方法在这里会失败,因为你正在传递一个字符串值得一提的是,这种方法会创建一个数据副本:如果OP担心性能,可能是因为集合太大,所以复制数据可能是不可行的。@DiegoMartinoia我认为他可以改变对象。当然,如果OP有一个基元数组,最好的办法就是进行自己的迭代并用结果创建一个新副本。