Dhiraj
Dhiraj

Reputation: 113

Remove elements from ArrayList while retaining the duplicates if any present

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

Answers (2)

uhs
uhs

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

GhostCat
GhostCat

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

Related Questions