Java - 在两个不同的数组中查找唯一元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44493858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 08:12:07  来源:igfitidea点击:

Java - Finding unique elements in two different arrays

javaarrays

提问by Aishu

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.

但在这里我得到了[1,2,3,4]作为输出。但预期的输出是[1,2,3,4,7,8]. 我不确定我在这里做错了什么。我以传统方式需要它。我不想使用任何内置方法来实现这一点。

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

注意:我觉得它不是重复的,因为提供的解决方案不是在两个数组上找到唯一元素。

回答by KishanCS

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);
    }
}

回答by Christophe Roussy

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

出于教育目的使用 HashSet,如果列表很大,这可能会非常快:

  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]
  }

回答by YCF_L

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

如果您使用的是 java 8,我建议您使用以下解决方案:

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

为了解决这个问题,我基于这个帖子:识别列表中的重复项

回答by wumpz

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

这是另一个流(Java 8)解决方案。使用流应该避免修改流之外的变量。

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.

这里的想法是合并列表,然后计算每个项目的出现次数。计数为 1 的所有项目仅在一个列表中。这些被收集到结果列表中。

    //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.

编辑:更改此答案以解决一个列表问题中的多个问题。

回答by Markus G.

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

您必须添加第二个 for 循环来检查 arr2 的元素是否在 arr1 中,因为您只检查 arr1 的元素是否在 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);

    }

回答by Haythem ROUIS

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 :

如果您使用的是 Java 8,则可以执行以下操作:

List resultList = list1.stream().filter(nbr ->  !list2.contains(nbr)).collect(Collectors.toList());
resultList.addAll(list2.stream().filter(nbr -> !list1.contains(nbr)).collect(Collectors.toList()));

回答by Goal Android

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;    
    }

}

回答by Muhammad Aasharib Nawshad

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;
    }

回答by himani tiwari

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);
}

回答by Nuwan Harshakumara Piyarathna

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 Order.

实际上,使用 Java TreeSet 有一个更简单的解决方案。java TreeSet 不包含重复元素。因此,您所要做的就是创建一个 TreeSet 并将所有元素添加到其中。它还保持了自然秩序。

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, 2, 3, 4, 5, 6, 7, 8]