From 0a2a2c48e3e69f30ab22c3343de05ea92c443c44 Mon Sep 17 00:00:00 2001 From: Jonathan Hedley Date: Mon, 16 Dec 2024 18:59:17 +1100 Subject: [PATCH] Simplified multi-root select dedupe Very previously required IdentityHashMap as Element.equals was a value test, but is now actually a reference test. --- src/main/java/org/jsoup/select/Selector.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jsoup/select/Selector.java b/src/main/java/org/jsoup/select/Selector.java index c0c574fbc4..5b0041f669 100644 --- a/src/main/java/org/jsoup/select/Selector.java +++ b/src/main/java/org/jsoup/select/Selector.java @@ -5,7 +5,7 @@ import org.jspecify.annotations.Nullable; import java.util.Collection; -import java.util.IdentityHashMap; +import java.util.HashSet; import java.util.stream.Stream; /** @@ -145,7 +145,8 @@ public static Stream selectStream(Evaluator evaluator, Element root) { } /** - Find elements matching the query. + Find elements matching the query, across multiple roots. Elements will be deduplicated (in the case of + overlapping hierarchies). @param query CSS selector @param roots root elements to descend into @@ -156,17 +157,14 @@ public static Elements select(String query, Iterable roots) { Validate.notNull(roots); Evaluator evaluator = QueryParser.parse(query); Elements elements = new Elements(); - IdentityHashMap seenElements = new IdentityHashMap<>(); - // dedupe elements by identity, not equality + HashSet seenElements = new HashSet<>(); // dedupe elements by identity, as .equals is == for (Element root : roots) { - final Elements found = select(evaluator, root); - for (Element el : found) { - if (seenElements.put(el, Boolean.TRUE) == null) { - elements.add(el); - } - } + selectStream(evaluator, root) + .filter(seenElements::add) + .forEach(elements::add); } + return elements; }