在Java中,检查列表是否包含另一个列表中的项目(两个列表具有相同类型)的最快方法是什么?

PAu*_*jla 5 java optimization list

假设我有一个名为 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;
     }
}
Run Code Online (Sandbox Code Playgroud)

在另一个类中,我有两个 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); 
     }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:这是实现这一目标的最快方法吗?如果没有,您能否向我展示一个更好的实施方案,以提高我的性能?列表大小并不总是 100,000。目前在我的平台上,100,000 个大小大约需要 2 分钟。假设它可以从 1 到 1,000,000 不等。

bco*_*rso 5

Set您想为此使用 a 。Set有一个contains方法可以在 O(1) 时间内确定一个对象是否在集合中。

List<MyClass>从 转换为时需要注意以下几点Set<MyClass>

  1. 你将失去元素的顺序
  2. 你将丢失重复的元素
  3. 你的MyClass需求hashcode()和实施应该equals()它们保持一致

要将您的转换ListSet您只需使用:

Set<MyObject> s1 = new HashSet<>(inList);
Set<MyObject> s2 = new HashSet<>(outList);
Run Code Online (Sandbox Code Playgroud)

Java 文档解释了如何查找两个集合的并集、交集和差集。特别是,您似乎对联盟感兴趣:

// transforms s2 into the union of s1 and s2. (The union of two sets 
// is the set containing all of the elements contained in either set.)
s2.addAll(s1)
Run Code Online (Sandbox Code Playgroud)