1717import static java .util .stream .Collectors .groupingBy ;
1818import static java .util .stream .Collectors .joining ;
1919import static java .util .stream .Collectors .toList ;
20- import static java .util .stream .Collectors .toMap ;
2120import static java .util .stream .StreamSupport .stream ;
2221import static org .assertj .core .api .recursive .comparison .ComparisonDifference .rootComparisonDifference ;
2322import static org .assertj .core .api .recursive .comparison .DualValue .DEFAULT_ORDERED_COLLECTION_TYPES ;
3534import java .util .LinkedHashSet ;
3635import java .util .List ;
3736import java .util .Map ;
37+ import java .util .Map .Entry ;
3838import java .util .Objects ;
3939import java .util .Optional ;
4040import java .util .Set ;
4646import java .util .concurrent .atomic .AtomicLongArray ;
4747import java .util .concurrent .atomic .AtomicReference ;
4848import java .util .concurrent .atomic .AtomicReferenceArray ;
49+ import java .util .function .Function ;
4950import java .util .regex .Pattern ;
51+ import java .util .stream .Collector ;
52+ import java .util .stream .Collectors ;
5053import java .util .stream .Stream ;
51-
5254import org .assertj .core .internal .DeepDifference ;
5355
5456/**
@@ -575,7 +577,7 @@ private static void compareUnorderedIterables(DualValue dualValue, ComparisonSta
575577 // It may be that expectedElement matches an actual element in a different hash bucket, to account for this, we check the
576578 // other actual elements for matches. This may result in O(n^2) complexity in the worst case.
577579 if (!expectedElementMatched ) {
578- for (Map . Entry <Integer , ? extends List <?>> actualElementsEntry : actualElementsGroupedByHashCode .entrySet ()) {
580+ for (Entry <Integer , ? extends List <?>> actualElementsEntry : actualElementsGroupedByHashCode .entrySet ()) {
579581 // avoid checking the same bucket twice
580582 if (actualElementsEntry .getKey ().equals (expectedHash )) continue ;
581583 Iterator <?> actualElementsIterator = actualElementsEntry .getValue ().iterator ();
@@ -627,6 +629,8 @@ private static <K, V> void compareSortedMap(DualValue dualValue, ComparisonState
627629
628630 Map <?, ?> actualMap = filterIgnoredFields ((Map <?, ?>) dualValue .actual , dualValue .fieldLocation ,
629631 comparisonState .recursiveComparisonConfiguration );
632+
633+ @ SuppressWarnings ("unchecked" )
630634 Map <K , V > expectedMap = (Map <K , V >) filterIgnoredFields ((Map <?, ?>) dualValue .expected ,
631635 dualValue .fieldLocation ,
632636 comparisonState .recursiveComparisonConfiguration );
@@ -636,9 +640,9 @@ private static <K, V> void compareSortedMap(DualValue dualValue, ComparisonState
636640 // no need to inspect entries, maps are not equal as they don't have the same size
637641 return ;
638642 }
639- Iterator <Map . Entry <K , V >> expectedMapEntries = expectedMap .entrySet ().iterator ();
640- for (Map . Entry <?, ?> actualEntry : actualMap .entrySet ()) {
641- Map . Entry <?, ?> expectedEntry = expectedMapEntries .next ();
643+ Iterator <Entry <K , V >> expectedMapEntries = expectedMap .entrySet ().iterator ();
644+ for (Entry <?, ?> actualEntry : actualMap .entrySet ()) {
645+ Entry <?, ?> expectedEntry = expectedMapEntries .next ();
642646 // check keys are matched before comparing values as keys represents a field
643647 if (!java .util .Objects .equals (actualEntry .getKey (), expectedEntry .getKey ())) {
644648 // report a missing key/field.
@@ -683,17 +687,29 @@ private static void compareUnorderedMap(DualValue dualValue, ComparisonState com
683687 }
684688
685689 private static Map <?, ?> filterIgnoredFields (Map <?, ?> map , FieldLocation fieldLocation ,
686- RecursiveComparisonConfiguration recursiveComparisonConfiguration ) {
687- Set <String > ignoredFields = recursiveComparisonConfiguration .getIgnoredFields ();
688- List <Pattern > ignoredFieldsRegexes = recursiveComparisonConfiguration .getIgnoredFieldsRegexes ();
690+ RecursiveComparisonConfiguration configuration ) {
691+ Set <String > ignoredFields = configuration .getIgnoredFields ();
692+ List <Pattern > ignoredFieldsRegexes = configuration .getIgnoredFieldsRegexes ();
689693 if (ignoredFields .isEmpty () && ignoredFieldsRegexes .isEmpty ()) {
690694 return map ;
691695 }
692696 return map .entrySet ().stream ()
693- .filter (e -> !recursiveComparisonConfiguration .matchesAnIgnoredField (fieldLocation .field (e .getKey ().toString ())))
694- .filter (e -> !recursiveComparisonConfiguration .matchesAnIgnoredFieldRegex (fieldLocation .field (e .getKey ()
695- .toString ())))
696- .collect (toMap (Map .Entry ::getKey , Map .Entry ::getValue ));
697+ .filter (e -> !configuration .matchesAnIgnoredField (fieldLocation .field (e .getKey ().toString ())))
698+ .filter (e -> !configuration .matchesAnIgnoredFieldRegex (fieldLocation .field (e .getKey ().toString ())))
699+ .collect (toMap (Entry ::getKey , Entry ::getValue ));
700+ }
701+
702+ // workaround for https://bugs.openjdk.org/browse/JDK-8148463
703+ private static <T , K , U > Collector <T , ?, Map <K , U >> toMap (Function <? super T , ? extends K > keyMapper ,
704+ Function <? super T , ? extends U > valueMapper ) {
705+ @ SuppressWarnings ("unchecked" )
706+ U none = (U ) new Object ();
707+ Collector <T , ?, Map <K , U >> downstream = Collectors .toMap (keyMapper , valueMapper .andThen (v -> v == null ? none : v ));
708+ Function <Map <K , U >, Map <K , U >> finisher = map -> {
709+ map .replaceAll ((k , v ) -> v == none ? null : v );
710+ return map ;
711+ };
712+ return Collectors .collectingAndThen (downstream , finisher );
697713 }
698714
699715 private static FieldLocation keyFieldLocation (FieldLocation parentFieldLocation , Object key ) {
0 commit comments