Home > Net >  Remove first element satisfying condition in java list
Remove first element satisfying condition in java list

Time:06-24

I have a list of objects and I want to remove the first of them satisfying some condition, something like:

mylist.removeFirstIf(some condition on object);

Thanks in advance for any help.

CodePudding user response:

for(int i = 0; i < list.size(); i   ) {
 Type g = list.get(i);
 if( /*g satisfies a condition*/ ) {
  List.remove(i);
  break;
 }
}

Break will stop the execution of your loop, only removing the first element.

CodePudding user response:

Stream the list for a match, then feed the match to the list's remove() method which will remove the first occurrence.

    list.stream()
        .filter(e -> e.getId().equals("FOO"))  // Condition here
        .findFirst()
        .ifPresent(list::remove);

That's the "look at me, I know streams" version. For the most efficient uselessly micro-optimized version you would use Iterator.

Iterator<Foo> itr = list.iterator();
while(itr.hasNext()) {
    if(itr.next().getId().equals("FOO")) {
        itr.remove();
        break;
    }
}

CodePudding user response:

Here's an iterator option:

for (Iterator<T> iterator = list.iterator();
     current = iterator.next() ;
     iterator.hasNext()) {
  if (yourPredicate.test(element)) {
    iterator.remove();
    break;
  }
}

CodePudding user response:

Here is a general purpose solution as it will remove the first object of any type that meets some test passed as an argument.

List<Integer> list1 = new ArrayList<>(List.of(1, 2, 3, 4, 5));
removeFirst(list1, (g)-> g%2 == 0); // remove first even value
System.out.println(list1);

List<Character> list2 = new ArrayList<>(List.of('A','B','c','D','e','F'));
removeFirst(list2, Character::isLowerCase); 
System.out.println(list2);

Or a specific Object based on a field of that object. Here a record is simply an immutable class so a class would also work.

record MyObject(String getName, int getId) {}
List<MyObject> list3 = new ArrayList<>(List.of(
        new MyObject("A", 2),
        new MyObject("B", 3),
        new MyObject("CC", 4),
        new MyObject("DD", 5),
        new MyObject("EEE", 6)));

Remove first object that has a name of length 2.

removeFirst(list3, (obj)->obj.getName().length() == 2);
System.out.println("list3");
list3.forEach(System.out::println);

prints

list1: [1, 3, 4, 5]

list2: [A, B, D, e, F]

list3
MyObject[getName=A, getId=2]
MyObject[getName=B, getId=3]
MyObject[getName=DD, getId=5]
MyObject[getName=EEE, getId=6]

  • Using generics allows this to work for any type T.
  • passing a Predicate<T> lambda allows for any condition to be applied.
public static <T> void removeFirst(List<T> list,
        Predicate<T> criteria) {
    for (int i = 0; i < list.size(); i  ) {
        if (criteria.test(list.get(i))) {
            list.remove(i);
            break;
        }
    }
}
  • Related