ConcurrentTree extends ConcurrentTreeNode<K, V> { public synchronized void add(final K[] path, final V value) { ConcurrentTreeNode<K, V> node = this; for (final K part : path) { if (node.getChild(part) == null) { node.addChild(new ConcurrentTreeNode<K, V>(part, node)); } node = node.getChild(part); } node.setValue(value); }  synchronized void add(final K[] path, final V value); synchronized V remove(final K[] path); V get(final K[] path); List<V> getMatches(final K[] path); @Override String toString();  }
@Test public void testAdd() { ConcurrentTree<String, String> tree = setupTree(); tree.add(delimiter.split("c"), "c"); assertEquals(tree.get(delimiter.split("c")), "c"); tree.add(delimiter.split("c"), "d"); assertEquals(tree.get(delimiter.split("c")), "d"); tree.add(delimiter.split("/c"), "e"); assertEquals(tree.get(delimiter.split("c")), "d"); assertEquals(tree.get(delimiter.split("/c")), "e"); tree.add(delimiter.split("c/ "), "f"); assertEquals(tree.get(delimiter.split("c")), "d"); assertEquals(tree.get(delimiter.split("c/ ")), "f"); tree.add(delimiter.split("a/c"), "g"); assertEquals(tree.get(delimiter.split("a/c")), "g"); tree.add(delimiter.split("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z"), "z"); assertEquals(tree.get(delimiter.split("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z")), "z"); tree.add(delimiter.split("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p assertEquals(tree.get(delimiter.split("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p assertEquals(tree.get(delimiter.split("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z")), "z"); }