从ArrayList中删除对象

时间:2014-07-29 01:52:05

标签: java arraylist

我有两个类,Image和Channel.Image有一个imageId,Channel有一个channelId,它唯一地标识一个Image和Channel对象。还有一些其他属性。

Image类还有一个channelId,我用它来确定图像被分配到哪个通道。 我分别有两个Image和Channel ArrayList。

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

现在,我想从图像列表中删除所有那些包含channelId的图像对象,这些图像对象存在于channelList的通道对象中。

截至目前,我正在迭代这两个列表,然后比较channelId,将Image对象放在TreeSet中,最后返回一个列表。您能帮我解决一个更简单或更高效的解决方案吗?

2 个答案:

答案 0 :(得分:2)

对于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)
    }
}

请注意,这是一种O(n ^ 2)算法,对于大型列表大小,它不会很好地扩展。有一些方法可以进一步优化它(请参阅@ dasblinkenlight的注释,但为了概念清晰,我将限制此答案的范围。

答案 1 :(得分:2)

n元素插入TreeSet需要O(n*log(n))次。但是,您不需要订购SetHashSet在一般情况下应该更快(当然,您仍然可能不幸使用哈希码)。

然后,您可以根据设置修改列表:

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();
}