2

I need to find the unique elements in two different arrays.

public static void main(String[] args) {
        // TODO Auto-generated method stub

        int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
        int[] arr2 = new int[] { 5, 6, 7, 8 };

        boolean contains = false;
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr2.length; j++) {
                if (arr1[i] == arr2[j]) {
                    contains = true;
                    break;
                }
            }

            if(!contains){
                list.add(arr1[i]);
            }
            else{
                contains = false;
            }
        }
        System.out.println(list);

    }

But here I'm getting [1,2,3,4] as output. But the expected output is [1,2,3,4,7,8]. I'm not sure what I'm doing wrong here. And I need it in a traditional way. I don't want to use any inbuilt methods to acheive this.

Note: I feel it is not a duplicate because, the solution provided is not finding the unique elements on two arrays.

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
Aishu
  • 1,310
  • 6
  • 28
  • 52
  • 1
    You only compare arr1 with arr2 not arr2 with arr1 – Jens Jun 12 '17 at 07:41
  • 2
    Your code finds all the elements of the first list which are not present in the second list. It doesn't find the elements of the second list not present in the first list. – Eran Jun 12 '17 at 07:41
  • @KishanCS - Have u tested that code whatever the link u shared – Aishu Jun 12 '17 at 07:50
  • I'm not sure why my question got downvoted. Please provide justification if u think it is not valid – Aishu Jun 12 '17 at 07:52
  • @KishanCS - No, it is not..I want to find unique elements in both the arrays. The link u provided will find unique elements in only one array(i.e arr1) – Aishu Jun 12 '17 at 07:56
  • Check the bellow answer – KishanCS Jun 12 '17 at 08:15

16 Answers16

8

This solves your problem:

public static void main(String[] args) {

    // Make the two lists
    List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 4, 5, 6);
    List<Integer> list2 = Arrays.asList(5, 6, 7, 8);
    // Prepare a union
    Set<Integer> union = new HashSet<Integer>(list1);
    union.addAll(list2);
    // Prepare an intersection
    Set<Integer> intersection = new HashSet<Integer>(list1);
    intersection.retainAll(list2);
    // Subtract the intersection from the union
    union.removeAll(intersection);
    // Print the result
    for (Integer n : union) {
        System.out.println(n);
    }
}
KishanCS
  • 1,357
  • 1
  • 19
  • 38
  • 1
    Makes good use of Java collection methods and should get more upvotes – Christophe Roussy Jun 12 '17 at 08:36
  • 1
    yes @ChristopheRoussy but it will not solve all the cases, did you check with duplicate just in one array try with this `List list1 = Arrays.asList(1, 2, 3, 4, 4, 5, 6); List list2 = Arrays.asList(5, 6, 7, 8);`, it will show `4` 2 times – Youcef LAIDANI Jun 12 '17 at 08:39
  • @YCF_L hmmm actually this is a school case where the asker does not want to rely on built-in methods ... ok my bad :) – Christophe Roussy Jun 12 '17 at 08:52
  • 2
    @YCF_L thanks for help . List list1 = Arrays.asList(1, 2, 3, 4, 4, 5, 6); List list2 = Arrays.asList(5, 6, 7, 8);, it will show 4 2 times I have updated to hashset now the above problem is resolved . – KishanCS Jun 12 '17 at 09:00
  • Yes using HashSet is the 'realworld' way to go for large lists, this is often omitted in schools where they focus too much on lists. – Christophe Roussy Jun 12 '17 at 09:36
3

Using HashSet, for educative purposes, which could be very fast if lists are big:

  public static void main(final String[] args) {
    final List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
    final Set<Integer> set1 = new HashSet<>(list1);

    final List<Integer> list2 = new ArrayList<>(Arrays.asList(5, 6, 7, 8));
    final Set<Integer> set2 = new HashSet<>(list2);

    set1.retainAll(set2); // Keep union.

    // Remove union to keep only unique items.
    list1.removeAll(set1);
    list2.removeAll(set1);

    // Accumulate unique items.
    list1.addAll(list2);

    System.out.println(new HashSet<>(list1));
    // [1,2,3,4,7,8]
  }
Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85
3

Actually, there is a more simple solution using Java TreeSet.java TreeSet doesn't contain duplicate elements. Therefore, all you have to do is create a TreeSet and adding all elements to it. It also keeps the natural (sorted) Order.

public static void main(String[] args) {
    int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
    int[] arr2 = new int[] { 5, 6, 7, 8 };
    TreeSet<Integer> set = new TreeSet<>();
    for (int i:arr1) {
        set.add(i);
    }
    for (int i:arr2) {
        set.add(i);
    }
    System.out.println(set);
}

output: [1, 2, 3, 4, 5, 6, 7, 8]

1

If you are using java 8 i would suggest this solution :

public static void main(String[] args) {
    int[] arr1 = new int[]{1, 2, 3, 4, 5, 6};
    int[] arr2 = new int[]{5, 6, 7, 8};

    List<Integer> list = new ArrayList<>();//create a list or Integers
    //add the values of the two arrays in this list
    list.addAll(Arrays.stream(arr1).boxed().collect(Collectors.toList()));
    list.addAll(Arrays.stream(arr2).boxed().collect(Collectors.toList()));

    //we need a set to check if the element is duplicate or not
    Set<Integer> set = new HashSet();
    List<Integer> result = new ArrayList<>(list);

    //loop throw your list, and check if you can add this element to the set
    // or not, if not this mean it is duplicate you have to remove it from your list
    list.stream().filter((i) -> (!set.add(i))).forEachOrdered((i) -> {
        result.removeAll(Collections.singleton(i));
    });

    System.out.println(result);
}

Output

[1, 2, 3, 4, 7, 8]

To solve this problem, i based to this posts : Identify duplicates in a List

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
1

And here another streaming (Java 8) solution. Using streams one should avoid modifying stream outside variables.

The idea here is to union the lists and then to count the occurance of each item. All items with count 1 are only in one list. Those are collected to the result list.

    //using here Integer instead of atomic int, simplifies the union.
    Integer[] arr1 = new Integer[]{1, 2, 3, 4, 5, 6};
    Integer[] arr2 = new Integer[]{5, 6, 7, 8};

    List<Integer> list = new ArrayList<>();
    list.addAll(new HashSet<>(Arrays.asList(arr1)));
    list.addAll(new HashSet<>(Arrays.asList(arr2)));

    System.out.println(
            list.stream()
                    .collect(groupingBy(identity(), counting()))
                    .entrySet().stream()
                    .filter(i -> i.getValue() == 1)
                    .map(i -> i.getKey())
                    .collect(toList())
    );

EDIT: Changed this answer to adress multiples within one list problem.

wumpz
  • 8,257
  • 3
  • 30
  • 25
0

You have to add a second for-loop to check if elements of arr2 are in arr1 cause you are only checking if elements of arr1 are in arr2

public static void main(String[] args) {
        // TODO Auto-generated method stub

        int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
        int[] arr2 = new int[] { 5, 6, 7, 8 };

        boolean contains = false;
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr2.length; j++) {
                if (arr1[i] == arr2[j]) {
                    contains = true;
                    break;
                }
            }

            if(!contains){
                list.add(arr1[i]);
            }
            else{
                contains = false;
            }
        }
       for (int i = 0; i < arr2.length; i++) {
            for (int j = 0; j < arr1.length; j++) {
                if (arr1[i] == arr2[j]) {
                    contains = true;
                    break;
                }
            }

            if(!contains){
                list.add(arr2[i]);
            }
            else{
                contains = false;
            }
        }
        System.out.println(list);

    }
Markus G.
  • 1,620
  • 2
  • 25
  • 49
0

A more optimized way would be using list iterators.

        int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
        int[] arr2 = new int[] { 5, 6, 7, 8 };

        List<Integer> list1 = IntStream.of(arr1).boxed().collect(Collectors.toList());
        List<Integer> list2 = IntStream.of(arr2).boxed().collect(Collectors.toList());

        Iterator list1Iter = list1.iterator();
        boolean contains = false;
        while(list1Iter.hasNext()) {
            int val1 = (int)list1Iter.next();
            Iterator list2Iter = list2.iterator();
            while(list2Iter.hasNext()) {
                int val2 = (int)list2Iter.next();
                if( val1 == val2) {
                    // remove duplicate
                    list1Iter.remove();
                    list2Iter.remove();
                }
            }
        }
        list1.addAll(list2);
        for( Object val : list1) {
            System.out.println(val);
        }

If you are using Java 8, you can do the following :

List resultList = list1.stream().filter(nbr ->  !list2.contains(nbr)).collect(Collectors.toList());
resultList.addAll(list2.stream().filter(nbr -> !list1.contains(nbr)).collect(Collectors.toList()));
Haythem ROUIS
  • 347
  • 2
  • 10
  • Your first solution also requires Java 8. –  Jun 12 '17 at 08:41
  • this solution have the same problem with duplicate just in one array try to use `int[] arr1 = new int[]{1, 2, 3, 4, 4, 5, 6}; int[] arr2 = new int[]{5, 6, 7, 8};` it will show you duplicate 4 – Youcef LAIDANI Jun 12 '17 at 08:41
  • @saka1029 : i only used java 8 to transform array to list. You can use that without Java 8 using simple for loops. – Haythem ROUIS Jun 12 '17 at 08:45
  • 1
    @YCF_L : Sure, but this is not the problem. Here we are trying to eliminate duplicates between two different arrays. Otherwise, if you want to eliminate all duplicates, just use a `Set` – Haythem ROUIS Jun 12 '17 at 08:48
0
import java.util.Scanner;
import java.io.*;


public class CandidateCode{
    static int count =0;
    public static void main(String args[])
    {

    int n,n1;
    Scanner sc=new Scanner(System.in);
    System.out.println("Enter no. of elements for first array");
    n=sc.nextInt();
    int arr[]=new int[n];
    System.out.println("Enter the elements of first array");
    for(int i=0;i<n;i++)
    {
        arr[i]=sc.nextInt();

    }
    System.out.println("Enter no. of elements for second array");
    n1=sc.nextInt();
    int arr1[]=new int[n1];
    System.out.println("Enter the elements of second array");
    for(int i=0;i<n1;i++)
    {
        arr1[i]=sc.nextInt();

    }
    unique_ele(arr,arr1);
    unique_ele(arr1,arr);
    System.out.println("The number of unique elements are");
    System.out.println(count);
    }
    public static int unique_ele(int arr2[],int arr3[])
    {
        boolean contains = false;
        for(int i=0;i<arr2.length;i++)
        {
            for(int j=0;j<arr3.length;j++)
            {
                if (arr2[i] == arr3[j]) {
                    contains = true;
                    break;
                }            

            }
             if(!contains){
               count++;
            }
            else{
                contains = false;
            }
        }

        return count;    
    }

}
0
public static ArrayList<Integer> findUniqueAmongLists(ArrayList<Integer> a, ArrayList<Integer> b){
        ArrayList<Integer> uniqueArr = new ArrayList<>();
        ArrayList<Integer> duplicateArr = new ArrayList<>();
        for(int i=0; i< a.size(); i++){
            if(!duplicateArr.contains(a.get(i))){
                uniqueArr.add(a.get(i));
                duplicateArr.add(a.get(i));
            }
            else{
                uniqueArr.remove(a.get(i));
            }
        }
        for(int j=0; j< b.size(); j++){
            if(!duplicateArr.contains(b.get(j))){
                uniqueArr.add(b.get(j));
                duplicateArr.add(b.get(j));
            }
            else{
                uniqueArr.remove(b.get(j));
            }
        }
        return uniqueArr;
    }
0
int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
    int[] arr2 = new int[] { 5, 6, 7, 8 };

    boolean contains = false;
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < arr1.length; i++) {
        for (int j = 0; j < arr2.length; j++) {
            if (arr1[i] == arr2[j]) {
                contains = true;
                break;
            }

        }

        if (!contains) {
            list.add(arr1[i]);

        } else {
            contains = false;
        }
    }

    for (int j = 0; j < arr2.length; j++) {
        for (int k = 0; k < arr1.length; k++) {
            if (arr2[j] == arr1[k]) {
                contains = true;
                break;
            }

        }
        if (!contains) {

            list.add(arr2[j]);
        } else {
            contains = false;
        }
    }
    System.out.println(list);
}
Unheilig
  • 16,196
  • 193
  • 68
  • 98
0
public class UniqueElementFrom2array {

    public static void main(String[] args) 
    {      
      int[] a= {1,2,3,4,5,6,7};
      int[] b= {1,2,3,8,9,4,10,11,12};
      int[] c=new int[a.length+b.length];
        int len1=a.length;
        int len2=b.length;
        System.arraycopy(a, 0, c, 0, len1);
        System.arraycopy(b, 0, c, len1,len2);
        Arrays.sort(c);
        System.out.println(Arrays.toString(c));
        Set s=new HashSet();
        
    for(int i=0;i<c.length;i++)
    {
        if(!s.contains(c[i]))
        {
            s.add(c[i]);
            System.out.print(c[i] + " "); 
        }
    }
    }
}
SSK
  • 3,444
  • 6
  • 32
  • 59
prakash k
  • 21
  • 2
0

A complete code using TreeSet in java.

import java.util.*;
import java.util.Scanner;
public class Main
{
    public static void uniqElements(int arr1[], int arr2[],int n){
        TreeSet<Integer> set1 = new TreeSet<>();
        TreeSet<Integer> set2 = new TreeSet<>();
        TreeSet<Integer> set3 = new TreeSet<>();
        TreeSet<Integer> set4 = new TreeSet<>();
        for (int i:arr1) {
            set1.add(i);
            set3.add(i);
        }
        for (int i:arr2) {
            set2.add(i);
            set4.add(i);
        }
        set3.addAll(set4);
        set1.retainAll(set2);
        set3.removeAll(set1);
        System.out.println(set3);
    
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr1 = new int[n];
        int[] arr2 = new int[n];
        for(int i =0;i<n;i++){
            arr1[i]=sc.nextInt();
        }
        for(int i =0;i<n;i++){
            arr2[i]=sc.nextInt();
        }
        uniqElements(arr1,arr2,n);
    
    }
}
SudhakarH
  • 541
  • 5
  • 16
0
    public static void main(String[] args) {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
        int[] arr2 = new int[] { 5, 6, 7, 8 };
        System.out.println(Stream.concat(Arrays.stream(arr1).boxed(), Arrays.stream(arr2).boxed()).distinct().collect(Collectors.toList()));
}
Jeets
  • 3,189
  • 8
  • 34
  • 50
0
  1. Merge all array.
  2. Remove elements at merged array that contains second array value.
import java.util.TreeSet;

public class ArrayUnique {
    public static void getUniqueElements(int arr1[], int arr2[]){

        // Merge all array with treeset 
        // it will remove duplicate element

        TreeSet<Integer> all= new TreeSet<>();
        TreeSet<Integer> secondArray= new TreeSet<>();
        
        for(int i:arr1){
            all.add(i);
        }
        for(int i:arr2){
            all.add(i);
            secondArray.add(i);
        }

        //Delete element that contains secondArray value
        all.removeAll(secondArray);

        //print to console
        System.out.println(all);
    }


    public static void main(String[] args) {
        
         int[] arr1 = {1,2,3,4};
         int[] arr2 = {1,3,5,10,16};
         getUniqueElements(arr1,arr2);

         //Result: [2,4]
    
    }
}


devtunus
  • 121
  • 1
  • 2
0

Try this:

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
    int[] arr2 = new int[] { 5, 6, 7, 8 };
    List<Integer> list = Stream.concat(Arrays.stream(arr1).boxed(), Arrays.stream(arr2).boxed()).distinct().collect(Collectors.toList());
    System.out.println(list);

}

hope this will resolve issue.

0

This will give you the unique values from two arrays;

public static String[] uniqueArr(String[] names1, String[] 
names2) 
{
Set<String> set = new HashSet<>(new
LinkedList<>(Stream.of(names1,
names2).flatMap(Stream::of).collect(Collectors.toList())));
String[] arr = new String[set.size()];
set.toArray(arr);
return arr;
}