Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintain an ArrayList of unique arrays in java

Tags:

java

arraylist

How can I maintain an ArrayList of unique arrays?

For instance, if I have the following arrays:

int [] a = {1,2,3};
int [] b = {2,1,3};
int [] c = {2,1,3};

According to my logic I am considering unique combinations. So in the case above a = b = c because they all contain "1", "2", "3".

Ideally I am wondering if there is a data structure in Java that recognizes this.

I tried the following:

Set<int []> result = new LinkedHashSet<>();
int [] x = {1,2,3};
int [] z = {2,1,3};
int [] m = {2,1,3};

result.add(x);
result.add(z);
result.add(m);

for(int [] arr: result){
    printArray(arr);
}

My output was:

1 2 3
2 1 3
2 1 3

Ideally I would want my output to only print one of the combinations above.

like image 675
Dinero Avatar asked Aug 13 '19 19:08

Dinero


People also ask

Does Java ArrayList maintain insertion order?

ArrayList maintains the insertion order i.e order of the object in which they are inserted. HashSet is an unordered collection and doesn't maintain any order. ArrayList allows duplicate values in its collection. On other hand duplicate elements are not allowed in Hashset.


2 Answers

You can create a method to add if not equals like so :

public static Set<int[]> addIfNotExist(Set<int[]> result, int[] array) {
    Arrays.sort(array);
    boolean check = result.stream()
            .anyMatch(a -> {
                Arrays.sort(a);
                return Arrays.equals(a, array);
            });
    if (check) {
        return result;
    } else {
        result.add(array);
        return result;
    }
}

Then you can call your method like so :

result = addIfNotExist(result, x);
result = addIfNotExist(result, z);
result = addIfNotExist(result, m);

Output

[1, 2, 3]

Or if you use a static Set, you can just use :

static Set<int[]> result = new LinkedHashSet<>();

public static void main(String[] args) {

    int[] x = {1, 2, 3};
    int[] z = {2, 1, 3};
    int[] m = {2, 1, 3};

    addIfNotExist(result, x);
    addIfNotExist(result, z);
    addIfNotExist(result, m);

    for (int[] arr : result) {
        System.out.println(Arrays.toString(arr));
    }
}

public static void addIfNotExist(Set<int[]> result, int[] array) {
    Arrays.sort(array);
    boolean check = result.stream()
            .anyMatch(a -> {
                Arrays.sort(a);
                return Arrays.equals(a, array);
            });
    if (!check) {
        result.add(array);
    }
}
like image 99
YCF_L Avatar answered Oct 21 '22 17:10

YCF_L


It definitely feels hacky and wrong, but you could use a TreeSet with a custom Comparator. Depending on your needs this might actually work, but at least note that this is breaking the general contract of the Set interface.

class Demo {
    public static void main(String[] args) throws Exception {
        Set<int[]> result = new TreeSet<>(new Hack());
        int[] x = {1,2,3};
        int[] z = {2,1,3};
        int[] m = {2,1,3};

        result.add(x);
        result.add(z);
        result.add(m);

        for (int[] arr : result) {
            System.out.println(Arrays.toString(arr));
        }
    }
}

class Hack implements Comparator<int[]> {

    @Override
    public int compare(int[] e1, int[] e2) {
        int[] copy1 = Arrays.copyOf(e1, e1.length);
        int[] copy2 = Arrays.copyOf(e2, e2.length);
        Arrays.sort(copy1);
        Arrays.sort(copy2);
        return Arrays.compare(copy1, copy2);
    }
}

Output:

[1, 2, 3]

If you are still on Java 8 use this Hack implementation:

class Hack implements Comparator<int[]> {

    @Override
    public int compare(int[] e1, int[] e2) {
        int[] copy1 = Arrays.copyOf(e1, e1.length);
        int[] copy2 = Arrays.copyOf(e2, e2.length);
        Arrays.sort(copy1);
        Arrays.sort(copy2);
        int cmp = Integer.compare(copy1.length, copy2.length);
        if (cmp != 0) {
            return cmp;
        }
        for (int i = 0; i < copy1.length; i++) {
            cmp = Integer.compare(copy1[i], copy2[i]);
            if (cmp != 0) {
                return cmp;
            }
        }
        return 0;
    }
}
like image 34
Marvin Avatar answered Oct 21 '22 16:10

Marvin