public Difference < BaseType > compareArraysWithId ( List < String > field1 , ArrayType node1 , List < String > field2 , ArrayType node2 , IdentityExtractor idex ) throws InvalidArrayIdentity , DuplicateArrayIdentity { Difference < BaseType > ret = new Difference <> ( ) ; // Build a map of identity -> index for both arrays final Map < Object , Integer > identities1 = getIdentityMap ( field1 , node1 , idex ) ; final Map < Object , Integer > identities2 = getIdentityMap ( field2 , node2 , idex ) ; // Iterate all elements of array 1 for ( Map . Entry < Object , Integer > entry1 : identities1 . entrySet ( ) ) { // Append index to the field name field1 . add ( Integer . toString ( entry1 . getValue ( ) ) ) ; // If array2 doesn't have an element with the same ID, this is a deletion Integer index2 = identities2 . get ( entry1 . getKey ( ) ) ; if ( index2 == null ) { ret . add ( new Removal ( field1 , getElement ( node1 , entry1 . getValue ( ) ) ) ) ; } else { field2 . add ( Integer . toString ( index2 ) ) ; // array2 has the same element // If it is at a different index, this is a move if ( index2 != entry1 . getValue ( ) ) { ret . add ( new Move ( field1 , field2 , getElement ( node1 , entry1 . getValue ( ) ) ) ) ; } // Recursively compare contents to get detailed diff ret . add ( compareNodes ( field1 , getElement ( node1 , entry1 . getValue ( ) ) , field2 , getElement ( node2 , index2 ) ) ) ; pop ( field2 ) ; } pop ( field1 ) ; } // Now check elements of array 2 that are not in array 1 for ( Map . Entry < Object , Integer > entry2 : identities2 . entrySet ( ) ) { if ( ! identities1 . containsKey ( entry2 . getKey ( ) ) ) { // entry2 is not in array 1: addition field2 . add ( Integer . toString ( entry2 . getValue ( ) ) ) ; ret . add ( new Addition ( field2 , getElement ( node2 , entry2 . getValue ( ) ) ) ) ; pop ( field2 ) ; } } return ret ; }
Computes difference between arrays whose elements can be identitied by a unique identifier