You don't need streams for this task, especially if you want to mutate the list of friends in-place:

students.forEach(s -> s.getFriends().removeAll(badKids));

And that's it. This uses the Collection.removeAll method.

Important: for this to work, the list of friends returned by the Student.getFriends() method must be mutable, such as ArrayList.


Despite the conciseness of the above solution, it breaks encapsulation, because we are mutating the list of friends of every student from outside the Student class. To fix this, you'd need to add a method to the Student class:

void removeBadKids(List<String> badKids) {
    friends.removeAll(badKids);
}

Thus, the solution would now become:

students.forEach(s -> s.removeBadKids(badKids));
Answer from fps on Stack Overflow
Top answer
1 of 1
3

Assuming you have a class PassengerBooking with a List of objects Flight, and that the passengerBooking variable represents a List of objects PassengerBooking.

You could traverse the items of your List. Then, for each PassengerBooking object retrieve the List of Flight with the corresponding getter and then invoke the removeIf method on the Collection returned.

public class Main {
    public static void main(String[] args) {
        List<PassengerBooking> passengerBooking = new ArrayList<>(List.of(
                new PassengerBooking(4, new ArrayList<>(List.of(
                        new Flight("AUS382"),
                        new Flight("ZOD498")
                )))
        ));

        System.out.println(passengerBooking);

        for (PassengerBooking passenger: passengerBooking){
            passenger.getFlights().removeIf(f -> f.getFlightNumber().equals("ZOD498"));
        }

        System.out.println(passengerBooking);
    }
}

Besides, if this is a common operation for your PassengerBooking class, you could think of implementing a custom method to remove a Flight by its id.

This is a simple assumption of your classes' implementation to test the code above.

class PassengerBooking {
    private int bookingId;
    private List<Flight> flights;

    public PassengerBooking(int bookingId, List<Flight> flights) {
        this.bookingId = bookingId;
        this.flights = flights;
    }

    public int getBookingId() {
        return bookingId;
    }

    public List<Flight> getFlights() {
        return flights;
    }

    //Custom utility method
    public void removeFlight(String flightID){
        flights.removeIf(f -> f.getFlightNumber().equals("ZOD498"));
    }

    @Override
    public String toString() {
        return String.format("%d => %s", bookingId, flights);
    }
}

class Flight {
    private String flightNumber;

    public Flight(String flightNumber) {
        this.flightNumber = flightNumber;
    }

    public String getFlightNumber() {
        return flightNumber;
    }

    @Override
    public String toString() {
        return flightNumber;
    }
}
Discussions

Remove Element in Nested List with Condition From another List - Java 8 - Stack Overflow
I want to remove items from a list with a conditional value that comes from another List. Here are the objects public class Student{ private String name; private String age; privat... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Filtering/removing from a nested List of Objects using streams in Java - Stack Overflow
Note that Stream#peek should normally only be used for the purpose of debugging and not mutating the stream elements. More on stackoverflow.com
๐ŸŒ stackoverflow.com
java - Removing elements of one list if present in another list using stream - Stack Overflow
I didn't find any thread here on this Question. I am trying to Remove elements (Cars in my case) of one list (cars1) if they present in another list (cars2) using Java stream. I tried using removeI... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Remove elements from a list by iterating via stream Java 8 - Stack Overflow
I want to remove some elements from my list of objects based on certain conditions. Can I do it with Java 8 streams? More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
How to do in Java
howtodoinjava.com โ€บ home โ€บ java streams โ€บ java โ€“ remove/update elements from list using stream
Java - Remove/Update Elements From List using Stream
September 20, 2022 - List<Employee> list = List.of( new Employee(1, "Alex", LocalDate.of(1990, 1, 2), 100d), new Employee(2, "Alok", LocalDate.of(1992, 1, 2), 200d), new Employee(3, "Brian", LocalDate.of(1994, 1, 2), 300d), new Employee(4, "Charles", LocalDate.of(1996, 1, 2), 400d)); List<Employee> modifiedList = list.stream() .filter(e -> e.getName().startsWith("A")) .collect(Collectors.toList()); //Employees whose names start with "A" System.out.println(modifiedList); The program output. [ Employee [id=1, name=Alex, dateOfBirth=1990-01-02, salary=100.0], Employee [id=2, name=Alok, dateOfBirth=1992-01-02, salary=200.0] ] To update all elements or the matching elements from the Stream, we use the Stream.map() method and return a new Employee instance.
๐ŸŒ
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 - List<Item> operatedList = new ArrayList<>(); itemList.stream() .filter(item -> item.isQualified()) .forEach(item -> { item.operate(); operatedList.add(item); }); itemList.removeAll(operatedList); Unlike removeIf that uses an Iterator, removeAll uses a simple for-loop to remove all the matching elements in the list. In this article, we looked at a way of operating on an item in Java 8 Streams and then removing it.
Find elsewhere
Top answer
1 of 3
3

Since you need your lists to be updated, in the below solution I am using removeIf method of the List to remove any elements which does not meet the necessary criteria. So for removeIf to work, the list should not be immutable. So replace the var list = List.of(...) code with var list = new ArrayList<>(List.of(...)); (Note: Null checks have been ignored as well.)

Now, this problem could be split into components:

  1. Predicate to identify if a list has any odd elements.
Predicate<OneDObject> hasOdd = obj-> obj.getList().stream().anyMatch(i -> i % 2 != 0);
  1. Predicate to remove objects from 2d list, which has odd elements in its 1d list.
Predicate<TwoDObject> validate2d = obj -> {
    // remove any 1d list that has atleast one odd number.
    obj.getList().removeIf(hasOdd);
    // check if there are any valid 1d lists
    return obj.getList().isEmpty();
};
  1. Now apply the predicate to the final list:
l5.removeIf(validate2d); // l5 will now contain only the 2d object having [2,4,6] list
2 of 3
1

Here's the final code (in Java, but I think it should almost be interchangeable with Kotlin)

List<TwoDObject> l6 = l5.stream()
                .peek(twoDObject -> {
                    List<OneDObject> filteredOneDObjectList = twoDObject.getList()
                            .stream()
                            .filter(oneDObject -> oneDObject.getList()
                                    .stream()
                                    .noneMatch(i -> i % 2 == 1))
                            .toList();

                    twoDObject.setList(filteredOneDObjectList);
                })
                .filter(twoDObject -> twoDObject.getList().size() > 0)
                .toList();

First we go through every twoDObject by calling Stream#peek, then stream its list and filter out every oneDObject, which contains an odd number. Then the list is saved back into the current twoDObject.

In the end we filter out all empty twoDObjects.


Note that Stream#peek should normally only be used for the purpose of debugging and not mutating the stream elements.
In this case it could also be replaced with

List<TwoDObject> l6 = l5.stream()
                .map(twoDObject -> {
                    ...

                    return twoDObject;
                })
                ...
๐ŸŒ
Techie Delight
techiedelight.com โ€บ home โ€บ java โ€บ remove elements from a list that satisfies a given predicate in java
Remove elements from a List that satisfies a given predicate in Java
1 week ago - Then we can use the removeAll() method provided by the List interface to remove elements of that collection from the original list. In Java 8, we can use Stream to remove elements from a list by filtering the stream easily.
๐ŸŒ
Mccue
mccue.dev โ€บ pages โ€บ 8-4-21-remove-items-with-stream
How to remove items using a stream
List<Integer> xs = List.of(1, 2, 3, 4); List<Integer> evens = xs.stream().filter(x -> x % 2 == 0).collect(Collectors.toList()); And for a map you would use Collectors.toMap if you need a map at the end. So "filter" is the answer ยท I see instead of removing you just create a new collection ยท Yeah, because a bunch of iterators don't support remove (like ArrayList's would, but not what you get from List.of(..)) if you are programming to the List or Map interface instead of a particular implementation it's safer to do a filter.
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();
                         }
                     }
                 }
              }
          }
       }
    }
    
๐ŸŒ
Baeldung
baeldung.com โ€บ home โ€บ java โ€บ java collections โ€บ removing elements from java collections
Removing Elements from Java Collections | Baeldung
January 8, 2024 - Removing, or rather, filtering elements using Stream is quite straightforward, we just need to create an instance of Stream using our Collection, invoke filter with our Predicate and then collect the result with the help of Collectors:
๐ŸŒ
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 - package com.mkyong.basic; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class IteratorApp4B { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); // Java 8 List<String> result = list .stream() .filter(x -> !"A".equals(x)) .collect(Collectors.toList()); System.out.println(result); } }
Top answer
1 of 4
2

Note that in the first method, you can do the following to simplify removal.

List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15));
list.removeIf(element -> element % 3 == 0);
System.out.println(list);

prints:

[1, 2, 4, 5, 7, 8, 10, 11, 13, 14]
2 of 4
1

Your methods should have some input parameters to represent sequences and return appropriate results instead of just printing them.

  • Sequence as List<Integer>:
    remove divisibles by 3;
    (optionally) ensure that the first number is 4;
    existing sequence not affected, new sequence is created and returned
public static List<Integer> removeDivisiblesBy3(List<Integer> seq) {
    return seq.stream()
        .dropWhile(x -> x != 4)  // optionally ensure to start from 4
        .filter(x -> x % 3 != 0) // keep NOT divisible by 3
        .collect(Collectors.toList());
}
  • Sequence as variable array of ints:
public static int[] removeDivisiblesBy3(int ... arr) {
    return IntStream.of(arr)
        .dropWhile(x -> x != 4)  // optionally ensure to start from 4
        .filter(x -> x % 3 != 0) // keep NOT divisible by 3
        .toArray();
}
  • Input sequence as String, output result - the string without spaces
    As mentioned in the comments it is enough to use String::replaceAll method to remove all unneeded whitespace characters from the input string:
public static String deleteBlanks(String str) {
    return str.replaceAll("\\s+", ""); // delete all whitespace characters
}

Tests:

System.out.println(removeDivisiblesBy3(Arrays.asList(1, 4, 6, 7, 9, 11, 12, 19, 22)));
System.out.println(Arrays.toString(removeDivisiblesBy3(1, 4, 6, 7, 9, 11, 12, 19, 22)));
System.out.println(deleteBlanks("Hello world, how are you?"));

Output:

[4, 7, 11, 19, 22]
[4, 7, 11, 19, 22]
Helloworld,howareyou?