简体   繁体   English

从ArrayList中删除对象

[英]Remove objects from ArrayList

I have two classes, Image and Channel.Image has an imageId and Channel has a channelId which uniquely identify an Image and Channel object.Some other attributes are also present. 我有两个类,Image和Channel.Image有一个imageId,Channel有一个channelId,它们唯一地标识Image和Channel对象,还存在其他一些属性。

Image class also has a channelId, using which I determine to which channel the image has been assigned to. 图像类也有一个channelId,通过它我可以确定图像已分配到哪个通道。 I have a two ArrayLists of Image and Channel respectively. 我分别有两个Image和Channel的ArrayLists。

    List<Image> imageList = getItemist("image");
    List<Image> channelList = getItemList("channel");

Now, I would like to remove all those image objects from the image list which contain channelId which are present in the channel objects of the channelList. 现在,我想从图像列表中删除所有包含在channelList的通道对象中的包含channelId的图像对象。

As of now, I am iterating the two lists and then comparing the channelId, putting the Image objects in a TreeSet and finally returning a list.Can you please help me with a solution that is simpler or more efficient ? 到目前为止,我正在迭代两个列表,然后比较channelId,将Image对象放入TreeSet中,最后返回一个列表。能否请我提供一个更简单或更有效的解决方案?

This sounds like a good use-case for a ListIterator : 这听起来像一个ListIterator的好用例:

ListIterator iter = imageList.listIterator(); 
Image curr = null;
while (iter.hasNext){
    curr = iter.next();
    for (Image img : chanelList){
        if (img.chanelId == curr.chanelId){ //assuming chanelId is a primitive 
            iter.remove(curr); //remove curr 
            break; //break from the for loop to go on to the next image in imageList
        }
       //implicit: else continue; (i.e. go on to check the next image in chanelList)
    }
}

Note that this is an O(n^2) algorithm that won't scale well for large list sizes. 请注意,这是O(n ^ 2)算法,不适用于大型列表。 There are ways to optimize it further (see @dasblinkenlight's comment, for one), but for purposes of conceptual clarity, I'll limit the scope of this answer to this. 有多种方法可以对其进行进一步优化(请参阅@dasblinkenlight的注释),但是出于概念上的清晰起见,我将对此的回答范围限于此。

Inserting n elements to a TreeSet requires O(n*log(n)) time. n元素插入TreeSet需要O(n*log(n))时间。 However you don't need the Set to be ordered. 但是,您不需要订购Set A HashSet should be faster in the average case (of course you can still be unlucky with the hash codes). 在一般情况下, HashSet应该更快(当然,您对哈希码仍然不走运)。

You can then modify the list based on the set: 然后,您可以根据设置修改列表:

HashSet<Integer> channelIds = new HashSet<>();
for (Image channel : channelList) {
    channelIds.add(channel.channelId);
}

// following removal code is specialized for lists that
// allow random access, like ArrayList
final int size = imageList.size();
int j = 0;
for (int i = 0; i < size; i++) {
    Image image = imageList.get(i);
    if (!channelIds.contains(image.channelId)) {
        imageList.set(j++, image);
    }
}
if (j < size) {
    imageList.subList(j, size).clear();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM