How to remove specific element from a list of list in java?

Viewed 998

I removed specific element from list of list using for loop and making deepCopy. Is there any other way to remove specific element from List of List?

import java.util.ArrayList;
import java.util.List;

public class HelloWorld{

     public static void main(String []args){
         List<ArrayList<String>> listA = new ArrayList<ArrayList<String>>();
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("cucumber");
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("carrot");
        ArrayList<String> list3 = new ArrayList<String>();
        list3.add("spinach");
        ArrayList<String> list4 = new ArrayList<String>();
        list4.add("kale");
        listA.add(list1);
        listA.add(list2);
        listA.add(list3);
        listA.add(list4);
        System.out.println("Original-->"+listA);

        List<List<String>> deepCopyOfListA = new ArrayList<List<String>>(listA);
        System.out.println("Deepcopy -->"+deepCopyOfListA);

        for (List<String> item : deepCopyOfListA) {
            if (item.contains("kale") || item.contains("cucumber")){
            listA.remove(item);
            }
        }
        System.out.println("Final-->"+listA);
    }
}

From the answers below, this seemed the most convenient. Using Iterator to remove the desired elements with if condition. Tested and it works great. Thanks everyone for your input.

Iterator<ArrayList<String>> itr = listA.iterator();
    while(itr.hasNext()) {
        List<String> item = itr.next();
        if ((item.contains("cucumber") || item.contains("kale"))) {
            itr.remove();
        }
4 Answers

As of , if you want to remove a certain element from the inner list, you have to first iterate the outer one and then use List::removeIf to the inner one:

// Mutates the original list
List<List<String>> outerList = ...            
for (List<String> innerList : outerList) {
    innerList.removeIf(item -> "cucumber".equals(item));
}

// Creates a new one while keeping the original untouched
List<List<String>> newList = outerList.stream()
    .map(innerList -> innerList.stream()
        .filter(item -> !"cucumber".equals(item))
        .collect(Collectors.toList()))
    .collect(Collectors.toList());

For the lower versions than 8, you should use a proper removal way using Iterator:

for (final List<String> innerList: outerList) {
    Iterator<String> iterator = innerList.iterator();
    while (iterator.hasNext()) {
        if ("cucumber".equals(item)) {
            iterator .remove();
        }
    }
}

In any case, use "cucumber".equals(item) rather than item.equals("cucumber") because the former one is null-friendly.

You can remove "cucumber" from the list of lists just by iterating the list. No need to create explicit iterator objects, no need to use the weird "stream" syntax. No need to create a copy either - deep or shallow. Of course, you may want to create a copy anyway, so that you still have the original values - but that's up to you.

List<List<String>> ListA=response.path("response.A");
for (List<String> item : ListA) {
    item.remove("cucumber");
}

Note that if any of the lists happen to contain more than one cucumber, this will remove only the first one.

DeepCopyOfListA.removeAll(
        ListA.stream()
        .filter(innerList -> innerList.stream()
           .anyMatch(str -> str.contains("cucumber")))
        .collect(Collectors.toList())
);

Also want to attract your attention, that according to Java Code Convention you should name your variables with lowercase (camel case, in fact). So, listA and deepCopyofListA.

It is not clear whether you want to remove the complete inner list (i.e. item) if it has the string, cucumber -OR- you want to remove just the string, cucumber from the inner lists (i.e. items). Given below are solutions for each of these scenarios.

To remove the complete inner list (i.e. item) if it has the string cucumber:

public void removeSpecificElement(Response response) {
    List<List<String>> listA = response.path("response.A");
    Iterator<List<String>> itr = listA.iterator();
    while(itr.hasNext()) {
        List<String> item = itr.next();
        if (item.contains("cucumber")) {
            itr.remove();
        }
    }
}

To remove just the string, cucumber from the inner list (i.e. item):

public void RremoveSpecificElement(Response response) {
    List<List<String>> listA = response.path("response.A");
    for (List<String> item : listA) {
        item.removeAll(Collections.singleton("cucumber"));
    }
}
Related