private static void compareLists(Delta delta, Collection deltas, LinkedList stack, ID idFetcher)
    {
        List srcList = (List) delta.srcValue;
        List targetList = (List) delta.targetValue;
        int srcLen = srcList.size();
        int targetLen = targetList.size();

        if (srcLen != targetLen)
        {
            delta.setCmd(LIST_RESIZE);
            delta.setOptionalKey(targetLen);
            deltas.add(delta);
        }

        final String sysId = "(" + System.identityHashCode(srcList) + ')';
        for (int i = targetLen - 1; i >= 0; i--)
        {
            final Object targetValue = targetList.get(i);
            String srcPtr = sysId + '{' + i + '}';

            if (i < srcLen)
            {   // Do positional check
                final Object srcValue = srcList.get(i);

                if (targetValue == null || srcValue == null)
                {
                    if (srcValue != targetValue)
                    {   // element was nulled out, create a command to copy it (no need to recurse [add to stack] because null has no depth)
                        copyListElement(delta, deltas, srcPtr, srcValue, targetValue, i);
                    }
                }
                else if (isIdObject(srcValue, idFetcher) && isIdObject(targetValue, idFetcher))
                {
                    Object srcId = idFetcher.getId(srcValue);
                    Object targetId = idFetcher.getId(targetValue);

                    if (targetId.equals(srcId))
                    {   // No need to copy, same object in same List position, but it's fields could have changed, so add the object to
                        // the stack for further graph delta comparison.
                        stack.push(new Delta(delta.id, delta.fieldName, srcPtr, srcValue, targetValue, i));
                    }
                    else
                    {   // IDs do not match?  issue a set-element-command
                        copyListElement(delta, deltas, srcPtr, srcValue, targetValue, i);
                    }
                }
                else if (!DeepEquals.deepEquals(srcValue, targetValue))
                {
                    copyListElement(delta, deltas, srcPtr, srcValue, targetValue, i);
                }
            }
            else
            {   // Target is larger than source - elements have been added, issue a set-element-command for each new position one at the end
                copyListElement(delta, deltas, srcPtr, null, targetValue, i);
            }
        }
    }
private static void compareLists ( Delta delta , Collection deltas , LinkedList stack , ID idFetcher ) { List srcList = ( List ) delta . srcValue ; List targetList = ( List ) delta . targetValue ; int srcLen = srcList . size ( ) ; int targetLen = targetList . size ( ) ; if ( srcLen != targetLen ) { delta . setCmd ( LIST_RESIZE ) ; delta . setOptionalKey ( targetLen ) ; deltas . add ( delta ) ; } final String sysId = "(" + System . identityHashCode ( srcList ) + ')' ; for ( int i = targetLen - 1 ; i >= 0 ; i -- ) { final Object targetValue = targetList . get ( i ) ; String srcPtr = sysId + '{' + i + '}' ; if ( i < srcLen ) { final Object srcValue = srcList . get ( i ) ; if ( targetValue == null || srcValue == null ) { if ( srcValue != targetValue ) { copyListElement ( delta , deltas , srcPtr , srcValue , targetValue , i ) ; } } else if ( isIdObject ( srcValue , idFetcher ) && isIdObject ( targetValue , idFetcher ) ) { Object srcId = idFetcher . getId ( srcValue ) ; Object targetId = idFetcher . getId ( targetValue ) ; if ( targetId . equals ( srcId ) ) { stack . push ( new Delta ( delta . id , delta . fieldName , srcPtr , srcValue , targetValue , i ) ) ; } else { copyListElement ( delta , deltas , srcPtr , srcValue , targetValue , i ) ; } } else if ( ! DeepEquals . deepEquals ( srcValue , targetValue ) ) { copyListElement ( delta , deltas , srcPtr , srcValue , targetValue , i ) ; } } else { copyListElement ( delta , deltas , srcPtr , null , targetValue , i ) ; } } }
Deeply compare two Lists and generate the appropriate 'resize' or 'set' commands
to rectify their differences.