1

I try to remove all the person under 18 years old from my list, so i have a class Person and this is what i tried in my Main:

import java.util.*;

public class Main {

    public static void main(String[] args) {
       
        Person person1 = new Person("Victor", 28, "meerdonk");
        Person person2 = new Person("Alex", 17, "antwerpen");
        Person person3 = new Person("Vlad", 15, "mechelen");

        List<Person> listOfPersons = List.of(person1, person2, person3);
   
        List<Person> adults = getLessThen18(listOfPersons); **//line 22**
        System.out.println(adults);
}   
 public static List<Person> getLessThen18(List<Person> personList) {

       for (Iterator<Person> iterator = personList.listIterator(); iterator.hasNext();){
           if (iterator.next().getAge() < 18 ) {
                iterator.remove(); **//line 40**
           }
       }
        return personList;
    }
}

So I try to iterate trough the list of persons and then if the person is under 18 to remove it. As i run the code i get this output :

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
    at java.base/java.util.ImmutableCollections$ListItr.remove(ImmutableCollections.java:380)
    at victor.Main.getLessThen18Iteration(Main.java:40)
    at victor.Main.main(Main.java:22)

Can someone please let me know what I did wrong?

  • 5
    why not just `return personList.stream().filter(p -> p.getAge() < 18).collect(Collectors.toList());`? – Federico klez Culloca Jan 18 '22 at 09:15
  • 3
    By the way, when asking a question like "what did I do wrong" you should also tell us how you know there's something wrong (errors, wrong results, etc...) – Federico klez Culloca Jan 18 '22 at 09:16
  • 1
    And now that I think about it, (minor side note) isn't the name of the method contradicting the fact that you're *removing* (not getting) people that are younger than 18? – Federico klez Culloca Jan 18 '22 at 09:18
  • 1
    "Can someone please let me know what I did wrong?" - For we'd need to know how you define "wrong", e.g. what problem you ran into. The `getLessThen18()` method should do the trick with one potential problem: it changes the input list which might not be desired. So you might want to build a new list instead and which case you'd not even need the explicit iterator. Just iterate over the persons and add only those whose age is 18+ to the new list which you return in the end. (What Federico is suggesting in his first comment is basically what I described here.) – Thomas Jan 18 '22 at 09:18
  • @FedericoklezCulloca , you are right indeed , it's working fine. Regarding error i sould post also my output? The error i get is –  Jan 18 '22 at 09:19
  • @BecaliNr1 please [edit] your question. Comments are not good for long outputs or errors. – Federico klez Culloca Jan 18 '22 at 09:23
  • 1
    Well ... one of the problems is that your `main` method is not declaring and initializing `listOfPersons`. There may also be problems in your `Person` class, which you haven't shown us. – Stephen C Jan 18 '22 at 09:23
  • @StephenC , indeed i forgot to add that here in my question :( , –  Jan 18 '22 at 09:28
  • @FedericoklezCulloca , sorry but what do you mean to edit my question ? –  Jan 18 '22 at 09:29
  • 1
    @BecaliNr1 Hit the "[Edit]" button underneath your question (or just the link in this comment) and edit your question to add all the relevant missing information. – Ivar Jan 18 '22 at 09:34
  • 2
    @BecaliNr1 "As i run the code i get the error that" that what? Please edit your question again to complete that sentence. – Federico klez Culloca Jan 18 '22 at 09:36
  • @FedericoklezCulloca , error added and lines added to the code where i cet the error . –  Jan 18 '22 at 09:38
  • 2
    Please let this be a good lessen for your next question. As you can see in the given answer, the issue was in the `List.of`, which you added only in the second last edit. Please make sure your question contains a [mcve] when asking future questions about not working code. – Ivar Jan 18 '22 at 09:43
  • 1
    @Ivar I will pay more attention for next time before i post my question :(, it seems i forrgot to select and copy that line and as given that line was the answer to my question . –  Jan 18 '22 at 09:56

2 Answers2

2

The problem here is the List.of. It returns an immutable List, which cannot be modified: Elements cannot be added, removed, or replaced.

Thus, you get an Exception when you try to call functions such as iterator.remove();.

There are these solutions:

  • Create a mutable List by copying the elements of the immutable List to a mutable one using a copy constructor:

    List<Person> listOfPersons = new ArrayList(List.of(person1, person2, person3));

  • Filter the existing List and create a new one (leaving the original List ontouched):

    return personList.stream().filter(person->person.getAge()<18).collect(Collectors.toList());

- Create a mutable List right away using Arrays.asList (which returns an ArrayList) List listOfPersons = Arrays.asList(person1, person2, person3);`

EDIT: Arrays.asList creates an ArrayList, but it's a different class (private static inside of Arrays) than anyone would assume..

f1sh
  • 11,489
  • 3
  • 25
  • 51
  • 1
    Thank you for this , this result it's good , so i will accept the one zho give it first , –  Jan 18 '22 at 09:49
  • Please note that Arrays.asList returns a fixed-sized list, so it is not "really" mutable and calling add/remove with it will still fail: https://stackoverflow.com/questions/46579074/what-is-the-difference-between-list-of-and-arrays-aslist – HectorLector Jan 18 '22 at 09:54
  • 1
    for my case i just replace : `List listOfPersons = List.of(person1, person2, person3);` with `List listOfPersons = new ArrayList(List.of(person1, person2, person3));` –  Jan 18 '22 at 09:57
  • @HectorLector interesting. I took a look at the [source code](http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/classes/java/util/Arrays.java#l3799) and `Arrays.asList` just calls `new ArrayList` internally, so I assumed it was safe to modify. EDIT: confusingly, there is an internal `ArrayList` class inside of `Arrays`, which cannot be modified. I will update the answer. – f1sh Jan 18 '22 at 10:01
2

Your code (List.of) creates an immutable list of persons:

    List<Person> listOfPersons = List.of(person1, person2, person3);

So calling remove/add will cause an Exception - as in your case.

Also your method name is misleading, since you are changing/mutating the passed list parameter and not return a new list (as suggested by the return value).

A possible way to do it would be:

 public static List<Person> getLessThen18(List<Person> personList) {
    return personList.stream()
                     .filter(person -> person.getAge() < 18)
                     .collect(Collectors.toList());   
 }
HectorLector
  • 1,851
  • 1
  • 23
  • 33