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
Related
I Have 2 ArrayList in my project. I want to get items which is not equal.
For Example:
LIST 1 - LIST 2
AB ------- AB
BA ------- BA
CC
I wanna get this CC. I'm doing like this:
ArrayList<String> alllist= new ArrayList<>(ArrayList<String> 1);
for (String i : ArrayList<String> 1) {
for (String j : ArrayList<String> 2) {
if (i.equals(j)) {
alllist.remove(i);
break;
}
}
}
This work if I haved 3 or 4 items in ArrayList but when I add 200 items this method doesn't work fine and getting wrong list.
Any idea? what can I do more?
Thanks a lot.
If I understand your question correctly, you are looking for a symmetric difference. You can use CollectionUtils.disjunction from Apache Commons Collections
Given:
List<String> list1 = Arrays.asList("AB", "BA", "DD");
List<String> list2 = Arrays.asList("AB", "BA", "CC");
Action:
System.out.println(CollectionUtils.disjunction(list1, list2));
Result:
[DD, CC]
If you need everything in list 1 but not list 2
1) Walk the first list and add each element to a HashSet.
2) use set.removeAll(list2) to remove everything in list 2.
The remainder is what's in list1 and not list2.
If you need to get everything in either list not in the other, you can repeat that in reverse. This should reverse the operation to O(n+m) where n is the length of list 1 and m is the length of list 2. Your pseudocode is O(n*m).
HashSet firstButNotSecond = new HashSet(list1);
firstButNotSecond.removeAll(list2);
HashSet secondButNotFirst = new HashSet(list2);
secondButNotFirst.removeAll(list1);
ArrayList<String> list2 = new ArrayList();
list2.add("AB");
list2.add("BA");
ArrayList<String> list1 = new ArrayList();
list1.add("AB");
list1.add("BA");
list1.add("C");
//remove all the element from the list1 which are also in list2
list1.removeAll(list2);
System.out.println("Result: " + list1); //only C will left behind
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.
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.
I am attempting to search through an array list to find a value (which may reoccur) and remove all instances of that value. I also would like to remove from a separate array list, values that are at the same location. Both ArrayLists are ArrayList<String>.
For example I am looking for the number 5 in ArrayList2:
ArrayList 1 ArrayList2
cat 1
pig 2
dog 5
chicken 3
wolf 5
Once I find the number 5, in both locations, I would like to remove dog and wolf from ArrayList1. My code has no errors but it doesn't seem to be actually removing what I am asking it.
//searching for
String s="5";
//for the size of the arraylist
for(int p=0; p<ArrayList2.size(); p++){
//if the arraylist has th value of s
if(ArrayList2.get(p).contains(s)){
//get the one to remove
String removethis=ArrayList2.get(p);
String removetoo=ArrayList1.get(p);
//remove them
ArrayList2.remove(removethis);
ArrayList1.remove(removetoo);
}
}
When I print the arrayLists they look largely unchanged. Anyone see what I am doing wrong?
When you are both looping and removing items from an array, the algorithm you wrote is incorrect because it skips the next item following each removal (due to the way in which you increment p). Consider this alternative:
int s = 5;
int idx = 0;
while (idx < ArrayList2.size())
{
if(ArrayList2.get(idx) == s)
{
// Remove item
ArrayList1.remove(idx);
ArrayList2.remove(idx);
}
else
{
++idx;
}
}
If you want to iterate over a collection and remove elements of the same collection, then you'll have to use an Iterator, e.g.:
List<String> names = ....
List<Integer> numbers = ....
int index = 0;
Iterator<String> i = names.iterator();
while (i.hasNext()) {
String s = i.next(); // must be called before you can call i.remove()
if (s.equals("dog"){
i.remove();
numbers.remove(index);
}
index++;
}
EDIT
In your case, you'll have to manually increment a variable to be able to remove items from the other List.
You could use two iterators:
Iterator<String> i1 = arrayList1.iterator();
Iterator<Integer> i2 = arrayList2.iterator();
while (i1.hasNext() && i2.hasNext()) {
i1.next();
if (i2.next() == s) {
i1.remove();
i2.remove();
}
}
Though as has been pointed out yet, it would probably be easier to use a map.
I think the contains method compares the two objects. However, the object "s" is different from the object in the ArrayList. You should use typed arrays (i.e. ArrayList) and make sure to compare values of each objects, not the objects themselves ...
You should declare your list as follows -
List<String> list1 = new ArrayList<String>();
//...
List<Integer> list2 = new ArrayList<Integer>();
//...
And instead of contains method use equals method.
Also to remove while iterating the lists use Iterator which you can get as follows -
Iterator<String> it1 = list1.iterator();
Iterator<Integer> it2 = list2.iterator();
//...
You might want to check the indexOf() method of ArrayList, but you have to be careful when removing from a list while iterating on it's elements.
Here's a straight forward solution:
List<Integer> origNums = new ArrayList<Integer>(nums);
Iterator<String> animalIter = animals.iterator();
Iterator<Integer> numIter = nums.iterator();
while (animalIter.hasNext()) {
animalIter.next();
// Represents a duplicate?
if (Collections.frequency(origNums, numIter.next()) > 1) {
// Remove current element from both lists.
animalIter.remove();
numIter.remove();
}
}
System.out.println(animals); // [cat, pig, chicken]
System.out.println(nums); // [1, 2, 3]
I agree with Makoto, using Map maybe more beneficial. If you will be searching only using the values of ArrayList2, then you have multiple values for one key.
For example, 5 refers to dog and wolf. For this you can add a list of values to the key - 5.
HashMap aMap = HashMap();
ArrayList key5 = new ArrayList();
key5.add("dog");
key5.add("wolf");
aMap.put(5, key5);
So when you need to remove all values for 5, you do
aMap.remove(5);
And it will remove the list containing dog and wolf.
i want to know how to remove duplicates in object.
for example
cat c[] = new cat[10];
c[1].data = "ji";
c[2].data = "pi";
c[3].data = "ji";
c[4].data = "lp";
c[5].data = "ji";
c[6].data = "pi";
c[7].data = "jis";
c[8].data = "lp";
c[9].data = "js";
c[10].data = "psi";
i would like to remove the duplicates value from object array.
thanks and advance
I assume you want to create another array which is duplicate free. (as you cannot change the size of an array)
You could implement hashCode and equals and use a HashSet, however without these you can create a Comparator.
However the simplest approach may be using the "Cat" class and "cats" array
Cat[] cats = { ... };
Set<String> datas = new HashSet<String>();
List<Cat> catList = new ArrayList<Cat>();
for(Cat cat: cats) if(datas.add(cat.data)) catList.add(cat);
Cat[] unqiueCats = catList.toArray(new Cat[catList.size()]);
Something like this should work? Make sure to import java.util.Arrays and java.util.HashSet.
/**
* Removes duplicates from an array. Objects in the array must properly
* implement hashCode() and equals() for this to work correctly.
*/
public static <E> E[] removeDuplicates(E[] array) {
// convert input array to populated list
List<E> list=Arrays.asList(array);
// convert list to populated set
HashSet<E> set=new HashSet<E>();
set.addAll(list);
// convert set to array & return,
// use cast because you can't create generic arrays
return (E[]) set.toArray();
}
You can create another temporary array, loop through the original array, and for each element, check if the value already in the temp array or not. If not, add it in.
You can also use Set and override the equals and hashCode method
Here's a quick hack to do what you wanted to (hopefully also compiles):
// Assuming the code in the question is here.
java.util.List<cat> tmp = new java.util.LinkedList<cat>();
java.util.HashSet<String> set = new HashSet<String>();
for (int i = 0; i < c.length; ++i)
if (set.put(c[i].data)) tmp.add(c[i]);
c = tmp.toArray(c);