title: Collectors.toSet() and HashSet
body: <p>Take the following line of sample code:</p>
  
  <pre><code>Set&lt;String&gt; someSet = someColletion.stream().map(p -&gt; p.toString()).collect(Collectors.toSet());
  </code></pre>
  
  <p>I want a <code>HashSet</code>. Taking a debugger to the code, I am indeed getting a <code>HashSet</code>. I had a look at <code>java.util.stream.Collectors.toSet()</code> to observe the following code:</p>
  
  <pre><code>public static &lt;T&gt; Collector&lt;T, ?, Set&lt;T&gt;&gt; toSet() {
      return new CollectorImpl&lt;&gt;((Supplier&lt;Set&lt;T&gt;&gt;) HashSet::new, Set::add,
                                 (left, right) -&gt; { left.addAll(right); return left; },
                                 CH_UNORDERED_ID);
  }
  </code></pre>
  
  <p>The contract <em>guarantees</em> a <code>Set</code>, and implementation decides on a <code>HashSet</code>; seems reasonable. However, my implementation needs the constant time lookup guaranteed by a <code>HashSet</code>, not just any old <code>Set</code>. If the implementation of <code>toSet()</code> decides to use say a <code>FooSet</code>, which is perfectly within its rights, my implementation is compromised.</p>
  
  <p>What is the best practise solution to this problem?</p>