title: How to merge multiple (arbitrary number of) Set<String> into one in Java?
body: <p>I have multiple <code>Set&lt;String&gt;</code> that I need to merge into one <code>Set&lt;String&gt;</code>. How do I do this operation in Java? Note, I am using using the <code>guava</code> API as best as I can to help out. For example, I have 3 classes as follows.</p>
  
  <pre><code>public class One {
   public static Set&lt;String&gt; SET = Sets.newHashSet("a","b","c");
  }
  public class Two {
   public static Set&lt;String&gt; SET = Sets.newHashSet("a","d","e","f");
  }
  public class Three {
   public static Set&lt;String&gt; SET = Sets.newHashSet("w","x","y","f");
  }
  </code></pre>
  
  <p>Now, I need to merge any combination of these sets into one. For, example, I may need to merge</p>
  
  <ul>
  <li><code>One.SET</code> + <code>Two.SET</code> + <code>Three.SET</code> into one to produce { "a","b","c","d","e","f","w","x","y" }, </li>
  <li><code>One.SET</code> + <code>Three.SET</code> into one to produce { "a","b","c","w","x","y","f" },</li>
  <li><code>Two.SET</code> + <code>Three.SET</code> into one to produce { "a","d","e","f","w","x","y" },</li>
  <li>and so on</li>
  </ul>
  
  <p>I created a method to merge an array of sets, <code>Set&lt;String&gt;[]</code>, but that doesn't work (explained here by this SO post <a href="https://stackoverflow.com/questions/7999192/creating-an-array-of-sets-in-java">Creating an array of Sets in Java</a>). Here's the code to merge. It works (compiles).</p>
  
  <pre><code>public static Set&lt;String&gt; immutableSetOf(Set&lt;String&gt;[] sets) {
   Set&lt;String&gt; set = new HashSet&lt;String&gt;();
   for(Set&lt;String&gt; s : sets) {
    set.addAll(s);
   }
   return ImmutableSet.copyOf(set);
  }
  </code></pre>
  
  <p>Here's the calling code; it doesn't work (doesn't compile).</p>
  
  <pre><code>Set&lt;String&gt; set = Utils.immutableSetOf(new Set&lt;String&gt;[] { One.SET, Two.SET });
  </code></pre>
  
  <p>So, I modified my merging method to operate on <code>List&lt;Set&lt;String&gt;&gt;</code> instead of <code>Set&lt;String&gt;[]</code>. Only the argument type changed, but I put it here for completeness.</p>
  
  <pre><code>public static Set&lt;String&gt; immutableSetOf(List&lt;Set&lt;String&gt;&gt; sets) {
   Set&lt;String&gt; set = new HashSet&lt;String&gt;();
   for(Set&lt;String&gt; s : sets) {
    set.addAll(s);
   }
   return ImmutableSet.copyOf(set);
  }
  </code></pre>
  
  <p>So, now my calling code looks like the following.</p>
  
  <pre><code>Set&lt;String&gt; set = Utils.immutableSetOf(
   Lists.newArrayList(
    One.SET, Two.SET));
  </code></pre>
  
  <p>This code does not compile, since <code>Lists.newArrayList(...)</code> is returning <code>Set&lt;String&gt;</code> and not <code>List&lt;Set&lt;String&gt;&gt;</code>. The method <code>Lists.newArrayList(...)</code> is overloaded, and the signature of the method that is used when I pass in sets is, <code>List.newArrayList(Iterable&lt;? extends E&gt; elements)</code>.</p>
  
  <p>So, the question is, how do I define a method to merge an arbitrary number of <code>Set&lt;String&gt;</code> while considering the calling code? I note that the compilation problems are on the calling code (not the merging method), but perhaps the solution also relates to the merging code? </p>
  
  <p>Update: I also tried varargs but that produces its own warning (<a href="https://stackoverflow.com/questions/1445233/is-it-possible-to-solve-the-a-generic-array-of-t-is-created-for-a-varargs-param">Is it possible to solve the &quot;A generic array of T is created for a varargs parameter&quot; compiler warning?</a>). The merging method signature is now the following.</p>
  
  <pre><code>public static Set&lt;String&gt; immutableSetOf(Set&lt;String&gt;... sets)
  </code></pre>
  
  <p>The calling code is now the following, and I get "Type safety: A generic array of Set is created for a varargs parameter".</p>
  
  <pre><code>Set&lt;String&gt; set = Utils.immutableSetOf(One.SET, Two.SET);
  </code></pre>
  
  <p>Update: For the accepted answer, I did the following.</p>
  
  <pre><code>@SuppressWarnings("unchecked")
  Set&lt;String&gt; set = Utils.immutableSetOf(Set[] { One.SET, Two.SET });
  </code></pre>