Java Check if two lists are mutually exclusive - java

Ok, I have List a and List b
is there a way to check that no value exist between the two?
List a // 1,2,4,5
List B // 1,6,7,8
Between both list // 1 FAILURE

Collections.disjoint(list1, list2)
returns true if they have no elements in common.

Use Collections.disjoint.
Returns true if the two specified collections have no elements in
common
boolean hasCommonElements = Collections.disjoint(listA, listB);

You can use Collections.disjoint():
public static boolean disjoint(Collection c1, Collection c2): Returns true if the two specified collections have no elements in common.
Code:
List<Integer> a = new ArrayList<Integer>();
List<Integer> b = new ArrayList<Integer>();
System.out.println(Collections.disjoint(a, b));

You have to user Collections.disjoint(a, b);
It returns a boolean: true if the lists have no elements in common.

Related

Java: list1=list2 // list1==list2?

what does list1=list2 and list1==list2 mean when we use ArrayLists?
ArrayList <String> list1, list2;
list1=new ArrayList<>(); list2=new ArrayList<>();
In Java, a single equal sign = is used to assign values to variables to be used later in your code, this is why it is called the assignment operator.
Two equal signs == is a comparative operation between two values which returns a Boolean. For instance 1 == 1 will return true, but I would be careful when using this operation with objects and would suggest using the equals() or compare() method.

Check if values in one arraylist is present in another

I need to check if any of the values in one arraylist is present in another arraylist:
import java.util.ArrayList;
public class SampleCode {
ArrayList<Integer> in = new ArrayList<>();
ArrayList<Integer> is = new ArrayList<>();
public static void main(String[] args) {
new SampleCode().work();
}
public void work(){
in.add(3);in.add(4);in.add(5);
is.add(1);is.add(2);is.add(3);
if(is.containsAll(in)){
System.out.println("It does not contain");
}
}
}
It prints "It does not contain". I need to know if there is a way to compare these two arraylists and if any of the values are present in the other arraylist, it should return false. I know iterating can help. Is there any simple way to do this?
I think you can use
Collections.disjoint
which says
Returns true if the two specified collections have no elements in common.
so it will return false if there are any elements in common.
Another possible solution:
public static boolean containsNone(List<?> list, List<?> of) {
List<?> temp = new ArrayList<Object>(list);
temp.retainAll(of);
return temp.isEmpty();
}
For example:
List<String> ref = Arrays.asList("w1", "w2", "w3");
List<String> ok = Arrays.asList("w4", "w5");
List<String> ko = Arrays.asList("w1", "w5");
System.out.println(containsNone(ok, ref));
System.out.println(containsNone(ko, ref));
Prints:
true
false
Try this one
public void work(){
in.add(3);in.add(4);in.add(5);;
is.add(1);is.add(2);is.add(3);;
ArrayList<Integer> matched = new ArrayList<Integer>(in);
matched.retainAll(is);
if(matched.size()>0){
System.out.println(matched);
}else{
System.out.println("It does not contain");
}
}
Collection.indexOfSubList(List<?> source, List<?> target)
Returns the starting position of the first occurrence of the specified
target list within the specified source list, or -1 if there is no
such occurrence.
More formally, returns the lowest index i such that source.subList(i, i+target.size()).equals(target), or -1 if there is no such index. (Returns -1 if target.size() > source.size().)
This implementation uses the "brute force" technique of scanning over the source list, looking for a match with the target at each location in turn.
Collections.disjoint(Collection<?> c1, Collection<?> c2)
Returns true if the two specified collections have no elements in
common.
Care must be exercised if this method is used on collections that do not comply with the general contract for Collection. Implementations may elect to iterate over either collection and test for containment in the other collection (or to perform any equivalent computation). If either collection uses a nonstandard equality test (as does a SortedSet whose ordering is not compatible with equals, or the key set of an IdentityHashMap), both collections must use the same nonstandard equality test, or the result of this method is undefined.
Care must also be exercised when using collections that have restrictions on the elements that they may contain. Collection implementations are allowed to throw exceptions for any operation involving elements they deem ineligible. For absolute safety the specified collections should contain only elements which are eligible elements for both collections.
Note that it is permissible to pass the same collection in both parameters, in which case the method will return true if and only if the collection is empty.
Throws:
NullPointerException - if one collection contains a null element and null is not an eligible element for the other collection. (optional) NullPointerException - if one collection contains a null element and null is not an eligible element for the other collection. (optional) ClassCastException - if one collection contains an element that is of a type which is ineligible for the other collection. (optional)
Collections.disjoint(list1, list2);
is your answer
see Collections documentation
public boolean isListNotOverlapping(List<Integer> yourList1, List<Integer> yourList2) {
for(Integer i : yourList1) {
if (yourList2.contains(i)) {
return false;
}
}
return true;
}

Obtaining array element differences in Java

Say I have two string arrays:
String[] first = new String[]{"12","23","44","67"};
String[] second= new String[]{"12","22","46","67"};
I searched for a function like PHP's array_diff which will give me the difference of these two arrays like this:
{"23","44"}
Is there a in-built function for this operation, or should I create a for loop and check for the differences ?
You can create two Sets from these arrays, like:
List<String> firstList = Arrays.asList(first);
List<String> secondList = Arrays.asList(second);
Set<String> firstSet = new HashSet<String>(first);
Set<String> secondSet = new HashSet<String>(second);
and then use the removeAll method:
firstSet.removeAll(secondList);
secondSet.removeAll(firstList);
so now firstList contains all the elements that are only available in the first array and secondList only the elements available in the second array.
A set that will contain only the elements available in one of the sets (without elements available in both sets) can be created using:
new HashSet<String>(firstSet).addAll(secondSet);
Guava's Sets class has a difference method.
so
Set<String> diff = Sets.difference(newHashSet(first), newHashSet(second));
PHP arrays are not arrays at all, that's why there is such weird method for diff.
If you want difference between two sets (A - B) in mathematical sense, then
1) use sets
Set<Integer> set1 = new HashSet<Integer>();
Set<Integer> set2 = new HashSet<Integer>();
2) use difference method (contains all elements in set1 that not in set2)
set1.removeAll(set2)
Note, this is assymetric difference.

check if elements of one ArrayList are present in other

I have two arraylist
ArrayList<String> a1
ArrayList<String> a2
I want to check if all the elements of a1 are present in a2.
this is what I was trying which I got from a question on SO
if (Arrays.asList(a2).containsAll(Arrays.asList(a1)))
{a2ContainsA1=true;}
which is not giving consistent results...is there any other way of doing this?
Not sure if I understand your question correctly, why are you using Arrays.asList() ?
Tried this:
ArrayList<String> a1 = new ArrayList<String>();
ArrayList<String> a2 = new ArrayList<String>();
a1.add("a");
a1.add("b");
a2.add("b");
a2.add("a");
System.out.println(a2.containsAll(a1));
And it outputs true
Adding an additional element to a1 will fail it (as expected):
ArrayList<String> a1 = new ArrayList<String>();
ArrayList<String> a2 = new ArrayList<String>();
a1.add("a");
a1.add("b");
a1.add("c");
a2.add("b");
a2.add("a");
System.out.println(a2.containsAll(a1));
And it outputs false
I think it would be easier to convert the two ArrayLists to Set objects then use set operations to determine if one is a subset of another. This will also satisfy #fge's comment about duplicity:
ArrayList<String> a1 = ...;
ArrayList<String> a2 = ...;
public boolean isSubset(ArrayList<String> a1, ArrayList<String> a2) {
Set<String> s1 = new HashSet(a1);
Set<String> s2 = new HashSet(a2);
return s1.containsAll(s2);
}
You already have your lists a1 and a2 here, and what you want is to tell whether all unique elements in a1 are also in a2. Therefore you just need to test for:
a1.containsAll(a2)
Arrays.asList() will build a list out of all elements you give as arguments (even if that "all elements" is only one element). In fact, your current code tries to see whether a single-element list which contains the list object a1 contains all elements in another single-element list containing the list object a2. And this is true if and only if lists a1 and a2 are equal, that is, if both of these lists contain the same elements at the same index, as per the List contract.
Which is certainly not what you were looking for!
you can loop through one of the arrays and do contains on each element therein
boolean a2ContainsA1 = true;
for(String str: a2){
if(!a1.contains(str)){
a2ContainsA1 = false;
}
You should try (assuming you don't want to keep a1 around, or else clone it)
boolean conditionVerified = a1.removeAll(a2).isEmpty();
You can use method isEqualList() of ListUtils like -
ArrayList<String> a1 = new ArrayList<String>();
ArrayList<String> a2 = new ArrayList<String>();
boolean isEqual = ListUtils.isEqualList(a1,a2);
boolean contains = true;
for(int i=0 ; i<a1.size() ; i++)
{
if(!a2.contains(a1[i])
contains = false;
}
Is this what you're looking for?
disjoint seems to be a good candidate here..
check if disjoint using !Collections.disjoint(list1, list2);
basic example at http://www.tutorialspoint.com/java/util/collections_disjoint.htm

Using contains on an ArrayList with integer arrays

I have an ArrayList<int[]>, and I add an array to it.
ArrayList<int[]> j = new ArrayList<int[]>();
int[] w = {1,2};
j.add(w);
Suppose I want to know if j contains an array that has {1,2} in it without using w, since I will be calling it from another class. So, I create a new array with {1,2} in it...
int[] t = {1,2};
return j.contains(t);
...but this would return false even though w was added to the list, and w contains the exact same array as t.
Is there a way to use contains such that I can just check to see if one of the elements of the ArrayList has the array value {1,2}?
Arrays can only be compared with Arrays.equals().
You probably want an ArrayList of ArrayLists.
ArrayList<ArrayList<Integer>> j = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> w = new ArrayList<Integer>();
w.add(1); w.add(2);
j.add(w);
ArrayList<Integer> t = new ArrayList<Integer>();
t.add(1); t.add(2);
return j.contains(t); // should return true.
The problem here is that arrays don't override Object.equals(Object), So the comparison between two list entries happens with the default equals() implementation
// from Object.class
public boolean equals(Object obj) {
return (this == obj);
}
So you have to iterate over the list and check all entries using Arrays.equals(int[], int[]). Here's a Helper method that does this:
public static boolean isInList(
final List<int[]> list, final int[] candidate){
for(final int[] item : list){
if(Arrays.equals(item, candidate)){
return true;
}
}
return false;
}
Update: Ever since Java 8, this has got a lot simpler:
public static boolean isInList(
final List<int[]> list, final int[] candidate) {
return list.stream().anyMatch(a -> Arrays.equals(a, candidate));
// ^-- or you may want to use .parallelStream() here instead
}
You need to iterate through the list and manually check whether an array matches your criteria.
public static boolean containsSubArray(List<int[]> j, int[] sub) {
for ( int[] arr : j ) {
if (arr contains elements of sub) {
return true;
}
}
return false;
}
If you want an exact match, you can make use of Arrays.equals(). I don't think there's a library function to do a contains all on an array though, so you would have to write that yourself if that's what you wanted.
"contains" contract checks for equality. So in your case what is failing is equality of int[]. Since Array does not override the equals method from Object you will need a workaround to check for containment.
If you need to check for containment within the Array then you are left with no choice but to iterate through the ArrayList and do the comparison yourself.
from java api:
public boolean contains(Object o)
Returns true if this list contains the
specified element. More formally,
returns true if and only if this list
contains at least one element e such
that (o==null ? e==null : o.equals(e)).
since int[] is a primitive, im pretty sure no .equals method exists so its my guess it would always return false.
I would recommend a different way of storing the data? maybe with a key of some sort?
Two java array arrays are equal iff they have the same object reference. Content doesn't matter.
You're looking for a way to check if they have an equal content. This could help:
Arrays.equals(new int[]{1,2}, new int[]{1,2}); // evaluates to true
Arrays.equals(new int[]{1,2}, new int[]{2,1}); // evaluates to false (!)
If order shouldn't affect equality, then you will have to implement a static equals method by yourself.
First they are not the same Object reference, so they are not equal. equals() will return false.
For your condition, you will need to implement a method to compare them yourself.
If you have one array and want to compare that all elements of array are present in list:
Long[] array1 = {1111L, 1112L};
Long[] array2 = {1111L, 1114L};
List<Long> list = new ArrayList<>();
list.add(1111L);
list.add(1112L);
list.add(1113L);
Arrays.asList(array1).stream().allMatch(val -> list.contains(val)); //return true
Arrays.asList(array2).stream().allMatch(val -> list.contains(val)); //return false

Categories