title: Java Combinations of elements of Map<A, List<B>>
body: <p>(ps. I just rewrote the question as I thought it was dealing with permutations, but it is actually dealing with combinations.)</p>
  
  <p>Consider more specifically a <code>Map&lt;String, List&lt;WordGroupAndScore&gt; baseMap</code>, with:</p>
  
  <pre><code>private static class WordGroupAndScore {
      public final WordGroup wordGroup;
      public final int score;
  
      public WordGroupAndScore(final WordGroup wordGroup, final int score) {
          this.wordGroup = wordGroup;
          this.score = score;
      }
  }
  </code></pre>
  
  <p>The <code>baseMap.size()</code> is variable, meaning that there can be any number of <code>String</code>s in the map. Also for every element in <code>baseMap</code>, <code>baseMap.get(i).size()</code> is variable. But the <code>baseMap</code> cannot contain empty lists.</p>
  
  <p>Now I am trying to find all possible combinations. The code itself is for checking data in invoices, not always all data is available on an invoice, hence the variable amount of <code>baseMap.size()</code>. And the list per element in <code>baseMap</code> is variable, because the amount of data found depends on which invoice it is.</p>
  
  <p>(Example data does not correspond one to one in the example, as in reality it is <code>WordGroupAndScore</code>, but I'll use <code>String</code>s or <code>BigDecimal</code>s to represent the data in the example)</p>
  
  <p>Example data of <code>baseMap</code> (values and key pairs) strictly (<code>A</code> and <code>List&lt;B&gt;</code> pairs):</p>
  
  <ul>
  <li><code>("invoiceNumber", ["0001", "0002"])</code></li>
  <li><code>("invoiceDate", ["2013-10-07"])</code></li>
  <li><code>("priceExclVAT, [new BigDecimal("10.00")])</code></li>
  <li><code>("highVAT, [new BigDecimal("2.10")])</code></li>
  <li><code>("priceInclVAT, [new BigDecimal("12.10"), new BigDecimal("14.10")])</code></li>
  </ul>
  
  <p>I want to generate all possible combinations of the data.</p>
  
  <p>Example output, one ("first") combination (values and single key pairs) strictly (<code>A</code> and <code>B</code> pairs):</p>
  
  <ul>
  <li><code>("invoiceNumber", "0001")</code></li>
  <li><code>("invoiceDate", "2013-10-07"])</code></li>
  <li><code>("priceExclVAT, new BigDecimal("10.00"))</code></li>
  <li><code>("highVAT, new BigDecimal("2.10"))</code></li>
  <li><code>("priceInclVAT, new BigDecimal("12.10"))</code></li>
  </ul>
  
  <p>Example output, one ("last") combination (values and single key pairs) strictly (<code>A</code> and <code>B</code> pairs):</p>
  
  <ul>
  <li><code>("invoiceNumber", "0002")</code></li>
  <li><code>("invoiceDate", "2013-10-07")</code></li>
  <li><code>("priceExclVAT, new BigDecimal("10.00"))</code></li>
  <li><code>("highVAT, new BigDecimal("2.10"))</code></li>
  <li><code>("priceInclVAT, new BigDecimal("14.10"))</code></li>
  </ul>
  
  <p>So somehow I need to iterate over the full <code>baseMap</code>, remember/create all combinations based on every <code>baseMap.get(i).size()</code>, but I am pretty much lost where to start. Biggest problem is that: how would I remember the combinations, because my <code>baseMap</code> is of variable size. If it would not have been variable, then I could've done it much easier.</p>
  
  <p>I hope the question is clear enough.</p>
  
  <p><strong>EDIT: Added one of my tries, which doesn't work.</strong></p>
  
  <pre><code>//Assumes that wordGroupsAndScores does not get changed during the process
  private void processWordGroupAndScores(TemplateBean template) {
      System.out.println();
      System.out.println("--wordGroupsAndScores--");
      for (Map.Entry&lt;String, List&lt;WordGroupAndScore&gt;&gt; entry : wordGroupsAndScores.entrySet()) {
          System.out.println("Attribute = " + entry.getKey());
          for (WordGroupAndScore wordGroupAndScore : entry.getValue()) {
              System.out.println("WordGroupAndScore = " + wordGroupAndScore);
          }
          System.out.println(";");
      }
      System.out.println();
      //create all possible unfinishedinvoices from wordgroupandscores
      int[] indices = new int[wordGroupsAndScores.keySet().size()];
      for (int index = 0; index &lt; indices.length; index++) {
          indices[index] = 0;
      }
      String[] keyLocation = new String[wordGroupsAndScores.keySet().size()];
      int j = 0;
      for (String key : wordGroupsAndScores.keySet()) {
          keyLocation[j] = key;
          j++;
      }
      processWordGroupAndScoresRecursive(indices, keyLocation, template);
  }
  
  private void processWordGroupAndScoresRecursive(int[] indices, String[] keyLocation, TemplateBean template) {
      processWordGroupAndScoresWithIndices(indices, keyLocation, template);
      boolean changedIndices = false;
      for (int index = indices.length - 1; index &gt;= 0; index--) {
          if (indices[index] &lt; wordGroupsAndScores.get(keyLocation[index]).size() - 1) {
              indices[index]++;
              changedIndices = true;
              break;
          }
      }
      if (changedIndices) {
          processWordGroupAndScoresRecursive(indices, keyLocation, template);
      }
  }
  
  private void processWordGroupAndScoresWithIndices(int[] indices, String[] keyLocation, TemplateBean template) {
      System.out.println();
      System.out.println("--Generated combination--");
      UnfinishedInvoice unfinishedInvoice = new UnfinishedInvoice();
      for (int index = 0; index &lt; indices.length; index++) {
          String key = keyLocation[index];
          WordGroupAndScore wordGroupAndScore = wordGroupsAndScores.get(key).get(indices[index]);
          System.out.println("Attribute = " + key);
          System.out.println("WordGroupAndScore = " + wordGroupAndScore);
          System.out.println(";");
          setUnfinishedInvoiceAttribute(key, unfinishedInvoice, Utils.joinWordGroup(wordGroupAndScore.wordGroup, " "), wordGroupAndScore.score);
      }
      System.out.println();
      unfinishedInvoice.verify();
      if (templateMap.containsKey(template)) {
          templateMap.get(template).add(unfinishedInvoice);
      }
      else {
          List&lt;UnfinishedInvoice&gt; list = new ArrayList&lt;&gt;();
          list.add(unfinishedInvoice);
          templateMap.put(template, list);
      }
  }
  </code></pre>
  
  <p>Let's take a more clear look at what it produces, let us only work with the indices, and not with real data anymore.</p>
  
  <p>Let's say this is the input: <code>[1, 1, 2, 1, 0]</code>. With it being the characterization of a map as a list, with as elements the index of the element in the lists inside the original map. We start by the combination where the last elements from the map is being taken.</p>
  
  <p>With my failing code we get as output:</p>
  
  <ul>
  <li><code>[1, 1, 2, 1, 0]</code></li>
  <li><code>[1, 1, 2, 0, 0]</code></li>
  <li><code>[1, 1, 1, 0, 0]</code></li>
  <li><code>[1, 1, 0, 0, 0]</code></li>
  <li><code>[1, 0, 0, 0, 0]</code></li>
  <li><code>[0, 0, 0, 0, 0]</code></li>
  </ul>
  
  <p>This is not correct as there are a lot of values missing, for example <code>[0, 0, 0, 1, 0]</code> is missing.</p>
  
  <p>What is going wrong here?</p>