diff --git a/assertj-bom/pom.xml b/assertj-bom/pom.xml
index cb393d0f62..ce3a08afb9 100644
--- a/assertj-bom/pom.xml
+++ b/assertj-bom/pom.xml
@@ -5,7 +5,7 @@
org.assertj
assertj-build
- 3.27.1
+ 3.27.2
assertj-bom
diff --git a/assertj-core/pom.xml b/assertj-core/pom.xml
index f137a631cf..8285cb1b2a 100644
--- a/assertj-core/pom.xml
+++ b/assertj-core/pom.xml
@@ -5,7 +5,7 @@
org.assertj
assertj-parent
- 3.27.1
+ 3.27.2
../assertj-parent
diff --git a/assertj-core/src/main/java/org/assertj/core/api/recursive/comparison/RecursiveComparisonDifferenceCalculator.java b/assertj-core/src/main/java/org/assertj/core/api/recursive/comparison/RecursiveComparisonDifferenceCalculator.java
index 21bd18b135..9a64fa463f 100644
--- a/assertj-core/src/main/java/org/assertj/core/api/recursive/comparison/RecursiveComparisonDifferenceCalculator.java
+++ b/assertj-core/src/main/java/org/assertj/core/api/recursive/comparison/RecursiveComparisonDifferenceCalculator.java
@@ -17,7 +17,6 @@
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
import static java.util.stream.StreamSupport.stream;
import static org.assertj.core.api.recursive.comparison.ComparisonDifference.rootComparisonDifference;
import static org.assertj.core.api.recursive.comparison.DualValue.DEFAULT_ORDERED_COLLECTION_TYPES;
@@ -35,6 +34,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -46,9 +46,11 @@
import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.function.Function;
import java.util.regex.Pattern;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
-
import org.assertj.core.internal.DeepDifference;
/**
@@ -575,7 +577,7 @@ private static void compareUnorderedIterables(DualValue dualValue, ComparisonSta
// It may be that expectedElement matches an actual element in a different hash bucket, to account for this, we check the
// other actual elements for matches. This may result in O(n^2) complexity in the worst case.
if (!expectedElementMatched) {
- for (Map.Entry> actualElementsEntry : actualElementsGroupedByHashCode.entrySet()) {
+ for (Entry> actualElementsEntry : actualElementsGroupedByHashCode.entrySet()) {
// avoid checking the same bucket twice
if (actualElementsEntry.getKey().equals(expectedHash)) continue;
Iterator> actualElementsIterator = actualElementsEntry.getValue().iterator();
@@ -627,6 +629,8 @@ private static void compareSortedMap(DualValue dualValue, ComparisonState
Map, ?> actualMap = filterIgnoredFields((Map, ?>) dualValue.actual, dualValue.fieldLocation,
comparisonState.recursiveComparisonConfiguration);
+
+ @SuppressWarnings("unchecked")
Map expectedMap = (Map) filterIgnoredFields((Map, ?>) dualValue.expected,
dualValue.fieldLocation,
comparisonState.recursiveComparisonConfiguration);
@@ -636,9 +640,9 @@ private static void compareSortedMap(DualValue dualValue, ComparisonState
// no need to inspect entries, maps are not equal as they don't have the same size
return;
}
- Iterator> expectedMapEntries = expectedMap.entrySet().iterator();
- for (Map.Entry, ?> actualEntry : actualMap.entrySet()) {
- Map.Entry, ?> expectedEntry = expectedMapEntries.next();
+ Iterator> expectedMapEntries = expectedMap.entrySet().iterator();
+ for (Entry, ?> actualEntry : actualMap.entrySet()) {
+ Entry, ?> expectedEntry = expectedMapEntries.next();
// check keys are matched before comparing values as keys represents a field
if (!java.util.Objects.equals(actualEntry.getKey(), expectedEntry.getKey())) {
// report a missing key/field.
@@ -683,17 +687,29 @@ private static void compareUnorderedMap(DualValue dualValue, ComparisonState com
}
private static Map, ?> filterIgnoredFields(Map, ?> map, FieldLocation fieldLocation,
- RecursiveComparisonConfiguration recursiveComparisonConfiguration) {
- Set ignoredFields = recursiveComparisonConfiguration.getIgnoredFields();
- List ignoredFieldsRegexes = recursiveComparisonConfiguration.getIgnoredFieldsRegexes();
+ RecursiveComparisonConfiguration configuration) {
+ Set ignoredFields = configuration.getIgnoredFields();
+ List ignoredFieldsRegexes = configuration.getIgnoredFieldsRegexes();
if (ignoredFields.isEmpty() && ignoredFieldsRegexes.isEmpty()) {
return map;
}
return map.entrySet().stream()
- .filter(e -> !recursiveComparisonConfiguration.matchesAnIgnoredField(fieldLocation.field(e.getKey().toString())))
- .filter(e -> !recursiveComparisonConfiguration.matchesAnIgnoredFieldRegex(fieldLocation.field(e.getKey()
- .toString())))
- .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
+ .filter(e -> !configuration.matchesAnIgnoredField(fieldLocation.field(e.getKey().toString())))
+ .filter(e -> !configuration.matchesAnIgnoredFieldRegex(fieldLocation.field(e.getKey().toString())))
+ .collect(toMap(Entry::getKey, Entry::getValue));
+ }
+
+ // workaround for https://bugs.openjdk.org/browse/JDK-8148463
+ private static Collector> toMap(Function super T, ? extends K> keyMapper,
+ Function super T, ? extends U> valueMapper) {
+ @SuppressWarnings("unchecked")
+ U none = (U) new Object();
+ Collector> downstream = Collectors.toMap(keyMapper, valueMapper.andThen(v -> v == null ? none : v));
+ Function