ConcurrentSuffixTree implements SuffixTree<O>, PrettyPrintable, Serializable { @Override public Iterable<KeyValuePair<O>> getKeyValuePairsForKeysContaining(final CharSequence fragment) { return new Iterable<KeyValuePair<O>>() { @Override public Iterator<KeyValuePair<O>> iterator() { return new LazyIterator<KeyValuePair<O>>() { Iterator<Set<String>> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); Iterator<String> keyIterator = Collections.<String>emptyList().iterator(); Set<String> keysAlreadyProcessed = new HashSet<String>(); @Override protected KeyValuePair<O> computeNext() { String originalKey = null; O value = null; while (value == null) { while (!keyIterator.hasNext()) { if (!originalKeysSets.hasNext()) { return endOfData(); } keyIterator = originalKeysSets.next().iterator(); } originalKey = keyIterator.next(); if (keysAlreadyProcessed.add(originalKey)) { value = valueMap.get(originalKey); } } return new ConcurrentRadixTree.KeyValuePairImpl<O>(originalKey, value); } }; } }; } 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 testGetKeyValuePairsForKeysContaining() throws Exception { ConcurrentSuffixTree<Integer> tree = newConcurrentSuffixTreeForUnitTests(); tree.put("BANANA", 1); tree.put("BANDANA", 2); assertEquals("[(BANANA, 1)]", Iterables.toString(tree.getKeyValuePairsForKeysContaining("ANAN"))); assertEquals("[(BANDANA, 2)]", Iterables.toString(tree.getKeyValuePairsForKeysContaining("DA"))); assertEquals("[(BANANA, 1), (BANDANA, 2)]", Iterables.toString(tree.getKeyValuePairsForKeysContaining("AN"))); assertEquals("[(BANANA, 1), (BANDANA, 2)]", Iterables.toString(tree.getKeyValuePairsForKeysContaining("BAN"))); assertEquals("[(BANANA, 1), (BANDANA, 2)]", Iterables.toString(tree.getKeyValuePairsForKeysContaining("ANA"))); assertEquals("[]", Iterables.toString(tree.getKeyValuePairsForKeysContaining("APPLE"))); assertEquals("[(BANANA, 1), (BANDANA, 2)]", Iterables.toString(tree.getKeyValuePairsForKeysContaining(""))); }