To Remove element from the list

objectA.removeIf(x -> conditions);

eg:

objectA.removeIf(x -> blockedWorkerIds.contains(x));

List<String> str1 = new ArrayList<String>();
str1.add("A");
str1.add("B");
str1.add("C");
str1.add("D");

List<String> str2 = new ArrayList<String>();
str2.add("D");
str2.add("E");

str1.removeIf(x -> str2.contains(x)); 

str1.forEach(System.out::println);

OUTPUT: A B C

Answer from uma shankar on Stack Overflow
🌐
Vultr
docs.vultr.com › java › standard library › java › util › arraylist › removeall()
Java ArrayList removeAll() - Remove Specified Elements
September 27, 2024 - The removeAll() method in Java's ArrayList class is a powerful tool for removing multiple elements from a list simultaneously based on the contents of another collection.
🌐
Baeldung
baeldung.com › home › java › java streams › operating on and removing an item from stream
Operating on and Removing an Item from Stream | Baeldung
January 8, 2024 - Internally, removeIf uses an Iterator to iterate over the list and match the elements using the predicate. We can now remove any matching elements from the list. We can also use another list to hold the elements that have been operated upon, ...
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › java › remove-elements-from-a-list-that-satisfy-given-predicate-in-java
Remove elements from a List that satisfy given predicate in Java - GeeksforGeeks
July 23, 2022 - Stream.filter() method can be used in Java 8 that returns a stream consisting of the elements that match the given predicate condition.
Top answer
1 of 3
1

Here come two possible solutions.

This one is short and concise, but does in fact not remove elements from list1 but utilizes a partitioning collector to create the two lists. Think of the partitioning collector as kind of a two-way filter: if your predicate is fulfilled, collect to one list, if it's not, collect to the other list. The predicate in our case actually is "does list2 contain an employee with the same ID as the stream element from list1?". In order to lower the actual overhead, the code prepares a list of IDs from list2 up-front.

        final List<String> list2Ids = list2.stream()
                .map(Employee::getId)
                .collect(Collectors.toList());

        Map<Boolean, List<Employee>> partitioned = list1.stream()
                .collect(Collectors.partitioningBy(e -> list2Ids.contains(e.getId())));

        list1 = partitioned.get(true);
        List<Employee> list3 = partitioned.get(false);

If you need to keep list1 - e.g. for memory foot-print reasons - and really have to remove the elements from it, I'd say you will have to stick to the really old-fashioned iterator. The reason for that is that iterators allow you to iterate some collection and remove elements while doing so. The next sample does exactly this. Note, that I prepared a list of IDs of list2 up-front again.

        final List<String> list2Ids = list2.stream()
                .map(Employee::getId)
                .collect(Collectors.toList());

        final List<Employee> list3 = new LinkedList<>();

        for (Iterator<Employee> iterator = list1.iterator(); iterator.hasNext();) {
            Employee next = iterator.next();

            if (!list2Ids.contains(next.getId())) {
                list3.add(next);
                iterator.remove();
            }
        }

2 of 3
0

Issues with your current code:

  • Remember as the rule of thumb: every time you're finding yourself changing something outside the stream using forEach, most likely something is going wrong (*have a look at the API documentation. You can invoke forEach() method on any type of collection without creating a stream, but keep in mind that using a multiline lambda inside forEach() doesn't bring you any advantage over a plain for loop.
  • it's highly advisable to give your variable clear self-explanatory names. Like emplDeparmentX, empleOldDB, etc. Names list1 makes more difficult to reason about the code.

You can address this problem in the following steps (time complexity of each step is linear):

  • create a Set of id contained in the list2 (remainder: the time complexity of the contains check is O(1));
  • generate the list of Employee (denoted as nonCommonId in the code) from the list1 that have no common id with Employee contained in the list2 by checking every id from the list1 against the Set obtained at the previous step.
  • Removing employees with different id from a list separately causes additional performance overhead because each removal has a linear time complexity. A better option will be to use removeAll().
  • apply removeAll() on the list id discard all the employee that are present in the list obtained at the previous step.

The overall time complexity O(n + m) (n and m - are numbers of elements in the list1 and list2).

Set<String> idSet = list2.stream()
    .map(Employee::id)
    .collect(Collectors.toSet());
            
List<Employee> nonCommonId = list1.stream()
    .filter(emp ->  !idSet.contains(emp.id()))
    .collect(Collectors.toList());
            
list1.removeAll(new HashSet<>(nonCommonId)); // list `nonCommonId` is wrapped by the HashSet to improve performance, because `removeAll()` relies on the `contains()` checks
// diplaying results
System.out.println("List1:");
list1.forEach(System.out::println);
            
System.out.println("nonCommonId:");
nonCommonId.forEach(System.out::println);

Output:

List1:
Employee[id=100, city=Boston, state=Massachusetts]
Employee[id=400, city=Atlanta, state=Georgia]
Employee[id=500, city=Cumming, state=Atlanta]
Employee[id=156, city=Duluth, state=Ohio]
nonCommonId:
Employee[id=300, city=pleasanton, state=California]
Employee[id=200, city=Decatur, state=Texas]
Employee[id=98, city=sula, state=Maine]

A link to Online Demo

🌐
TutorialsPoint
tutorialspoint.com › how-do-i-remove-multiple-elements-from-a-list-in-java
How do I remove multiple elements from a list in Java?
June 10, 2025 - import java.util.ArrayList; import java.util.List; public class RemoveMultipleElements { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); System.out.println("Original List: " + list); List<Integer> elementsToRemove = new ArrayList<>(); elementsToRemove.add(2); elementsToRemove.add(4); for (int i = 0; i < list.size(); i++) { if (elementsToRemove.contains(list.get(i))) { list.remove(i); i--; } } System.out.println("List after removal: " + list); } }
🌐
DigitalOcean
digitalocean.com › community › tutorials › java-list-remove-methods-arraylist-remove
How To Use remove() Methods for Java List and ArrayList | DigitalOcean
Learn how to use the remove() method in Java’s List and ArrayList interfaces with examples for removing by index or object.
🌐
How to do in Java
howtodoinjava.com › home › collections framework › java arraylist › arraylist removeif() in java: remove elements by condition
ArrayList removeIf() in Java: Remove Elements by Condition
1 week ago - Before Java 8, removing by condition meant an explicit Iterator. The loop does the same work as removeIf(), but each it.remove() on an ArrayList shifts the tail of the array, so many matches in a large list cost quadratic time.
Top answer
1 of 2
4

I think you can do it with stream by using removeIf and some condition :

list.removeIf(h -> h.getTokens().contains("INC") &&
        Arrays.stream(h.getTokens().split(";"))
                .filter(tag -> tag.contains("INC"))
                .map(tag -> tag.substring(tag.length() - 1))
                .filter("N"::equals)
                .anyMatch(v ->
                        (flag && !h.getPropertyA().equals(anotherObject.getPropertyAValue())) ||
                                (!flag && !h.getPropertyB().equals(anotherObject.getPropertyBValue()))));

Or you can separated the condition in a separated method, for example :

static void doAction(List<Hunt> list) {
    list.removeIf(MyClass::isCorrect);
}

private static boolean isCorrect(Hunt h) {
    return h.getTokens().contains("INC") &&
            Arrays.stream(h.getTokens().split(";"))
                    .filter(tag -> tag.contains("INC"))
                    .map(tag -> tag.substring(tag.length() - 1))
                    .filter("N"::equals)
                    .anyMatch(v ->
                            (flag && !h.getPropertyA().equals(anotherObject.getPropertyAValue())) ||
                            (!flag && !h.getPropertyB().equals(anotherObject.getPropertyBValue())));
}

Or as @Tom Hawtin - tackline suggest, you can use :

static void doAction(List<Hunt> list) {
    list.removeIf(h -> h.getTokens().contains("INC") &&
            Arrays.stream(h.getTokens().split(";"))
                    .anyMatch(tag -> tag.contains("INC") && tag.endsWith("N")
                            && !(flag ? h.getPropertyA().equals(anotherObject.getPropertyAValue())
                            : h.getPropertyB().equals(anotherObject.getPropertyBValue()))));
}
2 of 2
1

IMO stream API wont help you in this case! And this style of code is more readable in compared with stream based version. however I think you can make improvement by changing a bit.

  • Remove temporary variables such as String[] tags = h.getTokens().split(";"); and String value = tag.substring(tag.length() - 1);

  • Combine some conditions with together.

  • Use tag.charAt(tag.length() - 1) instead of tag.substring(tag.length() - 1);

    public static void doAction(List<Hunt> list) {
       for (ListIterator<Hunt> iter = list.listIterator(); iter.hasNext(); ) {
          Hunt h = iter.next();
          if (h.getTokens().contains("INC")) {
             for (String tag : h.getTokens().split(";")) {
                  if (tag.contains("INC") && tag.charAt(tag.length() - 1) == 'N') {
                     if (flag) {
                         if (!h.getPropertyA().equals(anotherObject.getPropertyAValue())) {
                            iter.remove();
                         }
                     } else {
                         if (!h.getPropertyB().equals(anotherObject.getPropertyBValue)) {
                            iter.remove();
                         }
                     }
                 }
              }
          }
       }
    }
    
🌐
Stack Overflow
stackoverflow.com › questions › 58000033 › java-8-removing-an-element-from-list
lambda - Java 8 removing an element from List - Stack Overflow
September 18, 2019 - Java 8 lambda get and remove element from list · 1 · Remove elements in a List using lambda · 1 · Java8 lambda remove element from List<?> and update the boolean flag value · 20 · How to remove elements from a list with lambda based on another list · 9 · Java 8 - For Each and removeIf ·
🌐
Dotnetcodr
dotnetcodr.com › 2015 › 02 › 14 › conditionally-remove-elements-from-a-list-in-java-8
Conditionally remove elements from a List in Java 8 | Exercises in .NET with Andras Nemes
August 29, 2015 - Java 8 introduces a new method available for Collection types: removeif(). It accepts a predicate which defines the condition on which the elements should be removed. It returns a boolean where a t…
🌐
Mkyong
mkyong.com › home › java › java – how to remove items from a list while iterating?
Java – How to remove items from a List while iterating? | mkyong.com
May 12, 2021 - Review the Java 8 Collection#removeIf method signature, and the API uses Iterator to remove the item while iterating it. ... package java.util; public interface Collection<E> extends Iterable<E> { //... default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator<E> each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; } //... }