我有两个类,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中,最后返回一个列表。您能帮我解决一个更简单或更高效的解决方案吗?
答案 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))
次。但是,您不需要订购Set
。 HashSet
在一般情况下应该更快(当然,您仍然可能不幸使用哈希码)。
然后,您可以根据设置修改列表:
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();
}