Tina
Tina

Reputation: 53

How to fix UnmodifiableLazyStringList

I have a ProtocolStringList protoList And I try to remove item "None" from this list

List<String> list = protoList.stream().collect(Collectors.toList());
list.remove("None");

Instead of I change the protoList into List, I still received an error like this

Error at com.google.protobuf.UnmodifiableLazyStringList$2.remove(UnmodifiableLazyStringList.java:180)
java.base/java.util.AbstractCollection.remove(AbstractCollection.java:299)

Upvotes: 1

Views: 886

Answers (3)

OhleC
OhleC

Reputation: 2950

Quoting the JavaDoc for Collectors#toList():

There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned; if more flexibility is required, use toCollection(Supplier)

The OpenJDK implementation uses an ArrayList, which would be mutable. You seem to be using an exotic JVM implementation that uses UnmodifiableLazyStringList for Strings?

Upvotes: 2

Stefan Warminski
Stefan Warminski

Reputation: 1845

You can avoid to get the element in your List via Stream#filter

List<String> list = protoList.stream()
    .filter(s -> !"None".equals(s))
    .collect(Collectors.toList());

AFAIK Collectors#toList provides an ArrayList (where it should be possible to remove elements) but you can't rely on it. So avoid collecting all elements of a Stream into a List and then modify List.

Upvotes: 0

Julia
Julia

Reputation: 21

List is an interface and not every implementation of it is modifiable.

Error at com.google.protobuf.UnmodifiableLazyStringList

If you want to get a list implementation that is modifiable (for example ArrayList) from a stream:

ArrayList<String> arrayList = (ArrayList<String>) protoList.stream().collect(Collectors.toCollection(ArrayList::new));
arrayList.remove("None");

Upvotes: 2

Related Questions