title: Efficiently comparing two lists of objects in Java
body: <p>I'm currently looking through two very large lists of <code>Peak</code> Objects, by overriding the <code>equals</code> method and looping through the two lists, comparing every peak to every other peak. Is there a more efficient way of doing this? My lists can be ~10,000 elements, which means up to 10000 * 10000 comparisons. </p>
  
  <p>The code for my peak object:</p>
  
  <pre><code>public class Peak extends Object{
  
  private final SimpleIntegerProperty peakStart;
  private final SimpleIntegerProperty peakEnd;
  private final SimpleIntegerProperty peakMaxima;
  private final SimpleIntegerProperty peakHeight;
  private final SimpleIntegerProperty peakWidth;
  private final SimpleStringProperty rname;
  
  public Peak(int peakStart, int peakEnd, int peakMaxima, int peakHeight, String rname) {
      this.peakStart = new SimpleIntegerProperty(peakStart);
      this.peakEnd = new SimpleIntegerProperty(peakEnd);
      this.peakMaxima = new SimpleIntegerProperty(peakMaxima);
      this.peakHeight = new SimpleIntegerProperty(peakHeight);
      this.peakWidth = new SimpleIntegerProperty(peakEnd - peakStart);
      this.rname = new SimpleStringProperty(rname);
  }
  
  public String getRname() {
      return rname.get();
  }
  
  public SimpleStringProperty rnameProperty() {
      return rname;
  }
  
  public int getPeakWidth() {
      return peakWidth.get();
  }
  
  public int getPeakHeight() {
      return peakHeight.get();
  }
  
  public int getPeakStart() {
      return peakStart.get();
  }
  
  public int getPeakEnd() {
      return peakEnd.get();
  }
  
  public int getPeakMaxima() {
      return peakMaxima.get();
  }
  
  @Override
  public String toString() {
      return "Peak{" +
              "peakStart= " + peakStart.get() +
              ", peakEnd= " + peakEnd.get() +
              ", peakHeight= " + peakHeight.get() +
              ", rname= " + rname.get() +
              '}';
  }
  
  @Override
  public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
  
      Peak peak = (Peak) o;
  
      if (!peakMaxima.equals(peak.peakMaxima)) return false;
      return rname.equals(peak.rname);
  }
  
  @Override
  public int hashCode() {
      int result = peakMaxima.hashCode();
      result = 31 * result + rname.hashCode();
      return result;
  }
  }
  </code></pre>
  
  <p>And my loop for comparing the objects is here. </p>
  
  <pre><code> List&lt;Peak&gt; interestingPeaks = new ArrayList&lt;&gt;();
  
              if(peakListOne != null &amp;&amp; peakListTwo != null){
                  for(Peak peak : peakListOne){
                      for(Peak peak2 : peakListTwo){
                          if(peak.equals(peak2)){ //number one, check the rnames match
                              if((peak2.getPeakHeight() / peak.getPeakHeight() &gt;= 9) || (peak.getPeakHeight() / peak2.getPeakHeight() &gt;= 9)){
                                      interestingPeaks.add(peak);
                              }
                          }
                      }
                  }
              }
  
              return interestingPeaks;
  </code></pre>
  
  <p>The code is basically matching the position of the maxima, and the <code>rname</code> , which is just a String. Then appending the peak to the <code>interestingPeaks</code> list if the height of one is a factor of 9x larger than the other. </p>