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;
}
}
}