Optimizer { public Optimizer removeDuplicates() { Set<Parser> uniques = new HashSet<>(); return add(parser -> { Optional<Parser> target = uniques.stream() .filter(each -> parser != each && parser.isEqualTo(each)).findFirst(); if (target.isPresent()) { return target.get(); } else { uniques.add(parser); return parser; } }); }  Optimizer add(Function<Parser, Parser> transformer); Optimizer removeDelegates(); Optimizer removeDuplicates(); Parser transform(Parser parser);  }
@Test public void testRemoveDuplicates() { Parser input = lowerCase().seq(lowerCase()); Parser output = new Optimizer().removeDuplicates().transform(input); assertTrue(input.isEqualTo(output)); assertNotEquals(input.getChildren().get(0), input.getChildren().get(1)); assertEquals(output.getChildren().get(0), output.getChildren().get(1)); }