title: Efficient way to compare two sets of different type
body: <p>First of all I need some very efficient solution as I am comparing collections with &gt;300k elements.</p>
  <p>At the beginning we have two different classes</p>
  <pre><code>Class A {
     String keyA;
     String keyB;
     String keyC;
  }
  
  Class B {
     String keyA;
     String keyB;
     String keyC;
     String name;
     String code;
  
     toA() {
       return new A(keyA, keyB, keyC);
     }
  }
  </code></pre>
  <p>Both of them contains several fields which are composed key(in this example key of three columns = keyA keyB keyC)</p>
  <p>This composed key makes calculation very long for primitive brute forces using nested loops.
  So I figured out that the most efficient way would be to transform second class to first one using method toA
  and then I can safely compare them using for example google's api using Sets efficiency</p>
  <pre><code>Set&lt;A&gt; collectionA = &lt;300k of elements&gt;
  Set&lt;B&gt; collectionB = &lt;300k of elements&gt;
  Set&lt;A&gt; collectionBConvertedToA = collectionB.stream().map(item -&gt; item.toA()).collect(toSet())
  
  Set&lt;A&gt; result = Sets.differences(collectionBConvertedToA, collectionA); // very fast first full scan comparison
  
  Set&lt;String&gt; changedNames = result.stream()
       .map(outer -&gt; collectionB.stream()
                                 // very slow second full scan comparison
                                .filter(inner -&gt; inner.getKeyA().equals(outer.getKeyA()) 
                                             &amp;&amp; inner.getKeyB().equals(outer.getKeyB()) 
                                             &amp;&amp; inner.getKeyC().equals(outer.getKeyC()))
                                .findFirst()
                                .map(item -&gt; item.getName()))
       .collect(toSet());
  log.info(&quot;changed names&quot; + changedNames);
  </code></pre>
  <p>Guava Sets.differences can find differences on Sets &gt;300k in less than 1/10 of second but later on I still have full scan anyway to collect names.</p>
  <p>I am just guessing, but is there something like</p>
  <pre><code>Set&lt;B&gt; result = Sets.differences(setA, setB, a -&gt; a.customHashCode(), b -&gt; b.customHashCode(), (a, b) -&gt; a.customEquals(b))
  </code></pre>
  <p>with custom hashCode and custom equals methods to keep Sets efficiency or there is some better pattern to make such comparison as I believe it seems like common problem ?</p>
  <p>EDIT
  I just figured out that I can just flip conversion to extended class</p>
  <pre><code>toB() {
    return new B(keyA, keyB, keyC, null, null);
  }
  </code></pre>
  <p>but then I need override hashCode and equals to use only those 3 fields and I still believe there is more elegant way</p>