ConcurrentSuffixTree implements SuffixTree<O>, PrettyPrintable, Serializable { @Override public Iterable<CharSequence> getKeysContaining(final CharSequence fragment) { return new Iterable<CharSequence>() { @Override public Iterator<CharSequence> iterator() { return new LazyIterator<CharSequence>() { Iterator<Set<String>> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); Iterator<String> keyIterator = Collections.<String>emptyList().iterator(); Set<String> keysAlreadyProcessed = new HashSet<String>(); @Override protected CharSequence computeNext() { String nextKey = null; while (nextKey == null) { while (!keyIterator.hasNext()) { if (!originalKeysSets.hasNext()) { return endOfData(); } keyIterator = originalKeysSets.next().iterator(); } nextKey = keyIterator.next(); if (!keysAlreadyProcessed.add(nextKey)) { nextKey = null; } } return nextKey; } }; } }; } ConcurrentSuffixTree(NodeFactory nodeFactory); @Override O put(CharSequence key, O value); @Override O putIfAbsent(CharSequence key, O value); @Override boolean remove(CharSequence key); @Override O getValueForExactKey(CharSequence key); @Override Iterable<CharSequence> getKeysEndingWith(CharSequence suffix); @Override Iterable<O> getValuesForKeysEndingWith(final CharSequence suffix); @Override Iterable<KeyValuePair<O>> getKeyValuePairsForKeysEndingWith(final CharSequence suffix); @Override Iterable<CharSequence> getKeysContaining(final CharSequence fragment); @Override Iterable<O> getValuesForKeysContaining(final CharSequence fragment); @Override Iterable<KeyValuePair<O>> getKeyValuePairsForKeysContaining(final CharSequence fragment); @Override int size(); @Override Node getNode();  }
@Test public void testGetKeysContaining() throws Exception { ConcurrentSuffixTree<Integer> tree = newConcurrentSuffixTreeForUnitTests(); tree.put("BANANA", 1); tree.put("BANDANA", 2); assertEquals("[BANANA]", Iterables.toString(tree.getKeysContaining("ANAN"))); assertEquals("[BANDANA]", Iterables.toString(tree.getKeysContaining("DA"))); assertEquals("[BANANA, BANDANA]", Iterables.toString(tree.getKeysContaining("AN"))); assertEquals("[BANANA, BANDANA]", Iterables.toString(tree.getKeysContaining("BAN"))); assertEquals("[BANANA, BANDANA]", Iterables.toString(tree.getKeysContaining("ANA"))); assertEquals("[]", Iterables.toString(tree.getKeysContaining("APPLE"))); assertEquals("[BANANA, BANDANA]", Iterables.toString(tree.getKeysContaining(""))); }