DependencyGraph { public DependencyGraph filter(Predicate<WordToken> predicate) { final SetMultimap<WordToken, Edge> filteredEdges = HashMultimap.create(); final Map<WordToken, Dependency> filteredDependent = new HashMap<>(); final SetMultimap<WordToken, Dependency> filteredGovernor = HashMultimap.create(); final SetMultimap<String, WordToken> filteredPartOfSpeech = HashMultimap.create(); edges.asMap().entrySet().stream() .filter(w -> predicate.test(w.getKey())) .forEach( e -> { final WordToken key = e.getKey(); e.getValue().stream() .filter(edge -> predicate.test(edge.getOther(key))) .forEach(v -> filteredEdges.put(key, v)); }); governors.asMap().keySet().stream() .filter(predicate) .forEach( k -> { final List<Dependency> filtered = governors.get(k).stream() .filter( d -> predicate.test(d.getGovernor()) && predicate.test(d.getDependent())) .collect(Collectors.toList()); filteredGovernor.putAll(k, filtered); }); dependents.keySet().stream() .filter(predicate) .forEach( k -> { final Dependency d = dependents.get(k); if (predicate.test(d.getGovernor()) && predicate.test(d.getDependent())) { filteredDependent.put(k, d); } }); partOfSpeech .asMap() .entrySet() .forEach( entry -> { final List<WordToken> filtered = entry.getValue().stream().filter(predicate).collect(Collectors.toList()); filteredPartOfSpeech.putAll(entry.getKey(), filtered); }); return new DependencyGraph( filteredEdges, filteredDependent, filteredGovernor, filteredPartOfSpeech); } private  DependencyGraph(); private  DependencyGraph(
      SetMultimap<WordToken, Edge> edges,
      Map<WordToken, Dependency> dependentMap,
      SetMultimap<WordToken, Dependency> governorMap,
      SetMultimap<String, WordToken> partOfSpeechMap); Dependency getDependency(WordToken word); Set<Dependency> getGovernors(WordToken word); Stream<WordToken> getEdges(WordToken word); Set<WordToken> extractWords(final int distance, final Dependency... start); Set<WordToken> extractWords(
      final int distance, Predicate<Dependency> predicate, final Dependency... start); Set<WordToken> extractWords(
      final int distance, Predicate<Dependency> predicate, final Collection<Dependency> start); Set<WordToken> nearestWords(final int distance, final WordToken... start); Set<WordToken> nearestWords(
      final int distance, Predicate<Dependency> predicate, final WordToken... start); Set<WordToken> nearestWords(
      final int distance, Predicate<Dependency> predicate, final Collection<WordToken> start); void log(); DependencyGraph filter(Predicate<WordToken> predicate); Set<WordToken> getWords(); List<WordToken> shortestPath(
      Collection<WordToken> from, Collection<WordToken> to, int maxDistance); static DependencyGraph build(final JCas jCas); static DependencyGraph build(final JCas jCas, AnnotationFS annnotation); void traverse(int distance, Collection<Dependency> start, TraversePredicate predicate); Collection<DependencyMatch> match(DependencyTree dependencyTree); Optional<WordToken> getHeadNode(Entity annotation); Optional<WordToken> getHeadNode(List<WordToken> covered); DependencyTree minimalTree(Collection<WordToken> tokens);  }
@Test public void testFilter() { final DependencyGraph subgraph = graph.filter(p -> p == a || p == sample); subgraph.log(); assertEquals(2, subgraph.getWords().size()); assertEquals(1, subgraph.getGovernors(sample).size()); }