code: public static <T> List<List<T>> getNGrams(List<T> items, int minSize, int maxSize) {
      List<List<T>> ngrams = new ArrayList<List<T>>();
      int listSize = items.size();
      for (int i = 0; i < listSize; ++i) {
        for (int ngramSize = minSize; ngramSize <= maxSize; ++ngramSize) {
          if (i + ngramSize <= listSize) {
            List<T> ngram = new ArrayList<T>();
            for (int j = i; j < i + ngramSize; ++j) {
              ngram.add(items.get(j));
            }
            ngrams.add(ngram);
          }
        }
      }
      return ngrams;
    }
docs: Get all sub-lists of the given list of the given sizes.
  
  For example:
  
  <pre>
  List&lt;String&gt; items = Arrays.asList(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;);
  System.out.println(CollectionUtils.getNGrams(items, 1, 2));
  </pre>
  
  would print out:
  
  <pre>
  [[a], [a, b], [b], [b, c], [c], [c, d], [d]]
  </pre>
  
  @param <T>
  The type of items contained in the list.
  @param items
  The list of items.
  @param minSize
  The minimum size of an ngram.
  @param maxSize
  The maximum size of an ngram.
  @return All sub-lists of the given sizes.