11

Possible Duplicate:
intersection/union of arraylists in java

Hello I have two string arrays.I want to print differences between two arrrays.Is there any java method for this? For example;

String[ ] first={"A","B","C"};
String[ ] second={"C","B"};

and result must be "A". Thanks for all comments.

Community
  • 1
  • 1
ademcu
  • 131
  • 1
  • 2
  • 6
  • Same as http://stackoverflow.com/questions/5283047/intersection-union-of-arraylists-in-java ? – CodeDreamer Dec 05 '12 at 21:01
  • 1. Does the order matter? 2. What about duplicate elements? 3. What about elements that are *added* in the second array? 4. What about the index of each difference?... --- Bottom line: could you please supply a few more less trivial examples so that we can understand what exactly you are asking? – thkala Dec 05 '12 at 22:09
  • 4
    This post is about difference, not intersection or union. It is not not covered by 5283047. – fredt Dec 05 '12 at 22:45
  • @fredt true, but we can get difference by intersecting, removing and joining :) – Oleg Mikheev Dec 05 '12 at 23:29
  • @Oleg, sure, but in a suboptimal way. This question is getting answers, is not covered by the existing question, and shouldn't be deleted. – fredt Dec 05 '12 at 23:46

2 Answers2

12

Convert array to Set<String>

new HashSet<String>(Arrays.asList(array));

and do

Set<String> commonOnes = biggerSet.retainAll(smallerSet);
biggerSet.removeAll(commonOnes).add(smallerSet.removeAll(commonOnes))

or use guava difference()

jmj
  • 237,923
  • 42
  • 401
  • 438
  • Will this get elements that are in the smaller array but not the larger one? – jonhopkins Dec 05 '12 at 21:01
  • This only works if: 1. The order doesn't matter, 2. The if an element shows up twice in one and once in the other still means equal. It might work for the asker but warning... – mprivat Dec 05 '12 at 21:01
  • 3
    duplicate element won't exist in Set – jmj Dec 05 '12 at 21:02
  • converting huge array to hashset will make performance go down to the ground – Oleg Mikheev Dec 05 '12 at 21:07
  • 1
    @fgb hmmm... not converting it to hashset, and using retainAll on a list? – Oleg Mikheev Dec 05 '12 at 21:40
  • 10
    `retainAll` returns a `boolean` and modifies the `Set`. The [Javadoc for the method](https://docs.oracle.com/javase/8/docs/api/java/util/Set.html#retainAll-java.util.Collection-) says, "...removes from this set all of its elements that are not contained in the specified collection." `removeAll` [behaves similarly](https://docs.oracle.com/javase/8/docs/api/java/util/Set.html#removeAll-java.util.Collection-). – Paul Jun 29 '16 at 20:52
5

This runs in O(n log n + m log m), where n is the size of first, and m is the size of second. Basically, it sorts the arrays, then pass through each one, adding ones that don't match to the LinkedList at each opportunity, then makes an array at the end. The earlier revision of this code did not work correctly because the trailing elements in the longer list were not getting added at the end.

public class SetDifference {
    public static void main(String... args) {
        String[] arrA = {"1", "2", "3", "4", "5", "25", "10"};
        String[] arrB = {"1", "2", "10", "4", "30"};

        System.out.println(Arrays.toString(differences(arrA, arrB)));
    }

    public static String[] differences(String[] first, String[] second) {
        String[] sortedFirst = Arrays.copyOf(first, first.length); // O(n)
        String[] sortedSecond = Arrays.copyOf(second, second.length); // O(m)
        Arrays.sort(sortedFirst); // O(n log n)
        Arrays.sort(sortedSecond); // O(m log m)

        int firstIndex = 0;
        int secondIndex = 0;

        LinkedList<String> diffs = new LinkedList<String>();  

        while (firstIndex < sortedFirst.length && secondIndex < sortedSecond.length) { // O(n + m)
            int compare = (int) Math.signum(sortedFirst[firstIndex].compareTo(sortedSecond[secondIndex]));

            switch(compare) {
            case -1:
                diffs.add(sortedFirst[firstIndex]);
                firstIndex++;
                break;
            case 1:
                diffs.add(sortedSecond[secondIndex]);
                secondIndex++;
                break;
            default:
                firstIndex++;
                secondIndex++;
            }
        }

        if(firstIndex < sortedFirst.length) {
            append(diffs, sortedFirst, firstIndex);
        } else if (secondIndex < sortedSecond.length) {
            append(diffs, sortedSecond, secondIndex);
        }

        String[] strDups = new String[diffs.size()];

        return diffs.toArray(strDups);
    }

    private static void append(LinkedList<String> diffs, String[] sortedArray, int index) {
        while(index < sortedArray.length) {
            diffs.add(sortedArray[index]);
            index++;
        }
    }
}
durron597
  • 31,968
  • 17
  • 99
  • 158
  • More code, but much better than the asList workarounds. +1! – ApproachingDarknessFish Dec 05 '12 at 21:55
  • this doesnt seem to work. I mean it almost works! for example, `code String[] arrA = {"1", "2", "3", "4", "5", "25", "10"}; String[] arrB = {"1", "2", "10", "4", "30"}; for these two arrays it returns 25,3,30. It leaves out 5. – OpenSource Mar 22 '16 at 14:04
  • @OpenSource Wow I bet it doesn't work a lot more thoroughly than that. Give me a few minutes. – durron597 Mar 22 '16 at 17:47