diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/StreamRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/StreamRules.java index e7bea74142..914c3705ff 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/StreamRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/StreamRules.java @@ -297,6 +297,22 @@ boolean after(Stream stream) { } } + /** + * Prefer an unconditional {@link Map#get(Object)} call followed by a {@code null} check over a + * call to {@link Map#containsKey(Object)}, as the former avoids a second lookup operation. + */ + static final class StreamMapFilter { + @BeforeTemplate + Stream before(Stream stream, Map map) { + return stream.filter(map::containsKey).map(map::get); + } + + @AfterTemplate + Stream after(Stream stream, Map map) { + return stream.map(map::get).filter(Objects::nonNull); + } + } + static final class StreamMin { @BeforeTemplate @SuppressWarnings("java:S4266" /* This violation will be rewritten. */) diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestInput.java index 5126726c3b..8450cdca75 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestInput.java @@ -141,6 +141,12 @@ boolean testStreamFindAnyIsPresent() { return Stream.of(1).findFirst().isPresent(); } + Stream testStreamMapFilter() { + return Stream.of("foo") + .filter(ImmutableMap.of(1, 2)::containsKey) + .map(ImmutableMap.of(1, 2)::get); + } + ImmutableSet> testStreamMin() { return ImmutableSet.of( Stream.of("foo").max(comparingInt(String::length).reversed()), diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestOutput.java index a11b7ca644..fe3fab7c4b 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StreamRulesTestOutput.java @@ -141,6 +141,10 @@ boolean testStreamFindAnyIsPresent() { return Stream.of(1).findAny().isPresent(); } + Stream testStreamMapFilter() { + return Stream.of("foo").map(ImmutableMap.of(1, 2)::get).filter(Objects::nonNull); + } + ImmutableSet> testStreamMin() { return ImmutableSet.of( Stream.of("foo").min(comparingInt(String::length)),