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()
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()
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++;
}
}
}
The issue with your code is that you are trying to use a non-existing constructor for ArrayList(int[] numbers) You either have to add every number from m and n to the ArrayList or use a double brace initialization e.g.
ArrayList < Integer > arr1 = new ArrayList < Integer > () {
{
for (int i: m) add(i);
}
}
ArrayList < Integer > arr2 = new ArrayList < Integer > () {
{
for (int i: n) add(i);
}
}
In one line it would look like this without formatting
new ArrayList<Integer>() {{for(int i:m) add(i);}};
The other preferred way would be to add every number while iterating e.g.
ArrayList<Integer> arr1 = new ArrayList<Integer>();
for(int i: m) arr1.add(i);
Does your code compile?
As someone else suggested, your ArrayList is of type Integer, not int. Here's an edit:
public static void main(String args[])
{
Difference obj = new Difference();
int a[] = {1,2,3,4,5};
int b[] = {1,2,3};
Integer[] anew = Arrays.stream(a).boxed().toArray( Integer[]::new );
Integer[] bnew = Arrays.stream(b).boxed().toArray( Integer[]::new );
System.out.println(obj.diff(anew,bnew));
}
Lastly, if you do use this, remember to change the arguments for diff to have type Integer.
You can keep a count for each value in the first array. You can use a HashMap to hold how many occurences you have for a specific value.
Then, for each value in the second array, you can decrease the already calculated count for this value. In the end, if the count for a specific value is 0, this would mean that there were the same number of appearances in the both arrays. Otherwise, one of the arrays contained more occurences of value. The number of differences for a specific value would be abs(count[value]) (as it can get negative, in the case when the second arrays contains more occurences of value than the first array).
This Java code illustrates the approach:
public List<Integer> findDiff(int[] first, int[] second) {
Map<Integer, Integer> count = new HashMap<>();
for (int value : first) {
int current = count.getOrDefault(value, 0);
count.put(value, current + 1);
}
for (int value : second) {
int current = count.getOrDefault(value, 0);
count.put(value, current - 1);
}
List<Integer> result = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : count.getEntrySet()) {
int diff = entry.getValue();
int times = Math.abs(diff);
for (int i = 0; i < times; i++) {
result.add(entry.getKey());
}
}
return result;
}
Clearly, we have a linear complexity for both time and memory.
Almost certainly not an optimal solution, but as something you can hopefully work with:
private static <X> Collection<X> findDiff(final Collection<X> a, final Collection<X> b) {
// Copy the Collections so you don't modify inputs
// and so you can safely 'remove' from them.
final List<X> aCopy = new ArrayList<>(a);
final List<X> bCopy = new ArrayList<>(b);
// Remove all common elements from the copies
// Using 'removeAll' will pull out duplicates,
// so do this one-by-one.
for (final X bElement : b) {
aCopy.remove(bElement);
}
// Note it's important to iterate over 'a' here, not
// aCopy since the elements of aCopy (may) have had some
// entries 'remove'd.
for (final X aElement : a) {
bCopy.remove(aElement);
}
// Combine the two cleared out lists to find
// the cumulative difference.
final List<X> diff = new ArrayList<>(aCopy);
diff.addAll(bCopy);
return Collections.unmodifiableCollection(diff);
}
Note, you can convert your int[] to a Collection<Integer> using something simple like:
IntStream.of(arr).boxed().collect(Collectors.toList());
Note also: you can do this with fewer intermediate Collections. You only need to copy one of the input ones if you don't mind modifying the inputs. And you don't need to combine the two into a new diff one. This was just something to work with (and more explanatory).
From what I see you just try to see if they are equal, if this is true, just go with something like this:
boolean areEqual = Arrays.equals(arr1, arr2);
This is the standard way of doing it.
Please note that the arrays must be also sorted to be considered equal, from the JavaDoc:
Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. In other words, two arrays are equal if they contain the same elements in the same order.
Sorry for missing that.
use Arrays.equals(ary1,ary2); // returns boolean value
EDIT
you can use Arrays.deepEquals(ary1,ary2) to compare 2D arrays as well
also check this link for comparision comparision between Arrays.equls(ar1,ar2) and Arrays.deepEquals(ar1,ar2)
Java Arrays.equals() returns false for two dimensional arrays
EDIT 2
if you dont want to use these library methods then you can easily implement your method like this:
public static boolean ArrayCompare(int[] a, int[] a2) {
if (a==a2) // checks for same array reference
return true;
if (a==null || a2==null) // checks for null arrays
return false;
int length = a.length;
if (a2.length != length) // arrays should be of equal length
return false;
for (int i=0; i<length; i++) // compare array values
if (a[i] != a2[i])
return false;
return true;
}