Reputation: 113
I need to remove some elements from an ArrayList.
I used removeAll(List)
method.
But the problem with this is it removes the duplicates as well.
How do I retain the duplicates?
Consider below example -
I have a List a1 = {2, 3, 4, 5, 2, 2, 3}
Now I have another
List a2 = {2, 3}
When I use a1.removeAll(a2)
I get a1 = {4, 5}
This removes all the instances of 2 and 3.
What I need is a1 = {4, 5, 2, 2, 3}
Just the number of instances present in a2 should be removed from a1.
How can I do this?
Upvotes: 1
Views: 68
Reputation: 848
You can try using map as this avoids n*m time complexity. Keep count of all elements in a1 & a2 . Then decrement the a1 count & add it to new Arraylist based on the a1 count map.
public class Test {
public static void main(String [] args) {
List<Integer> a1 = Arrays.asList(2, 3, 4, 5, 2, 2, 3);
List<Integer> a2= Arrays.asList(2,3);
Map<Integer,Integer> a1Count = new HashMap<>();
Map<Integer,Integer> a2Count = new HashMap<>();
a1.forEach(a -> {
int count = a1Count.get(a)==null ? 0: a1Count.get(a);
a1Count.put(a, count+1);
});
a2.forEach(a -> {
int count = a2Count.get(a)==null ? 0: a2Count.get(a);
a2Count.put(a, count+1);
});
a1Count.forEach((key,value) -> {
if(a2Count.containsKey(key)) {
a1Count.put(key, value-a2Count.get(key));
}
});
List<Integer> removed = new ArrayList<>();
a1Count.forEach((key,value) -> {
if(value>0) {
for(int i= 0; i<value;i++) {
removed.add(key);
}
}
});
System.out.print(removed);
}
Upvotes: -1
Reputation: 140417
Iterate the second list and for each member call remove() on the first list. You can't do this with a single call.
And be sure to invoke remove(Object) - instead of remive(int)! In other words: makes sure that you pass an Integer object. Otherwise you will be invoking the wrong method that removes a certain index!
Upvotes: 5