【发布时间】:2015-10-29 00:54:13
【问题描述】:
假设我有一个名为 MyClass 的类,如下所示:
public class MyClass
{
//Identifier is alpha-numeric. If the identifier starts will 'ZZ'
//is special special identifier.
private String identifier = null;
//Date string format YYYY-MM-DD
private String dateString = null;
//Just a flag (not important for this scenario)
private boolean isCoolCat = false;
//Default Constructor and getters/setters implemented
//Overrides the standard Java equals() method.
//This way, when ArrayList calls contains() for MyClass objects
//it will only check the Date (for ZZ identifier)
//and identifier values against each other instead of
//also comparing the isCoolCat indicator value.
@Override
public boolean equals(Object obj)
{
if(this == obj)
{
return true;
}
if(obj == null)
{
return false;
}
if(getClass() != obj.getClass())
{
return false;
}
MyClass other = (MyClass) obj;
if(this.identifier == null)
{
if(other.identifier != null)
{
return false;
}
} else if(!this.identifier.equals(other.identifier)) {
return false;
}
if(other.identifier.startsWith("ZZ"))
{
if(!this.dateString.equals(other.dateString))
{
return false;
}
}
return true;
}
}
在另一个类中,我有两个 MyClass 类型的 List,每个包含 100,000 个对象。我需要检查一个列表中的项目是否在另一个列表中,我目前完成此操作如下:
`
List<MyClass> inList = new ArrayList<MyClass>();
List<MyClass> outList = new ArrayList<MyClass>();
inList = someMethodForIn();
outList = someMethodForOut();
//For loop iterates through inList and check if outList contains
//MyClass object from inList if it doesn't then it adds it.
for(MyClass inObj : inList)
{
if(!outList.contains(inObj))
{
outList.add(inObj);
}
}
我的问题是:这是完成此任务的最快方法吗?如果不能,您能否向我展示一个更好的实现,它将给我带来性能提升?列表大小并不总是 100,000。目前在我的平台上,100,000 大小大约需要 2 分钟。假设它可以在 1 到 1,000,000 之间变化。
【问题讨论】:
-
List#retainAll(Collection),应该返回列表之间所有相同元素的List。最快的,也许不是,最简单的,可能是(别忘了,你要先复制原始的List;)) -
@MadProgrammer 我也不确定这是否会更快。还需要更多内存,因为现在我必须复制可以包含 1,000,000 个对象的列表。此外,retainAll 将返回两个列表之间所有相同元素的列表。但这将如何帮助我确定哪些对象 inList 不在 outList 中,以及如何将它们添加到 outList 中?我认为这种方法不会更快。
-
好吧,如果您使用
LinkedList,内存将是一个问题,因为您只维护对对象的引用,而不是新副本;)。inList.retainAll(outList)将返回一个List,其中包含来自inList的所有对象,这些对象在outList中,使用outList.retainAll(inList)进行反向操作。当然,您也可以使用removeAll,这将在不匹配的实体上留下List;) -
@MadProgrammer 从设计的角度来看,这是我最喜欢的答案。在代码中,这将经过很好的测试和理解。
标签: java list optimization