1

I have a class like this

@Getter
public class MyClass  {

    private Collection<String> headers;

    public myConfig(DownloadRequest downloadRequest) {

        this.headers = downloadRequest.getHeaders() == null ? new ArrayList() : downloadRequest.getHeaders();
    }
 }

When I run this it gives me java.lang.UnsupportedOperationException.

As I use headers in another function and do getHeaders().clear(), I get this error.

Return type of downloadRequest.getHeaders() is Collection<String>

I am unable to figure out what I can cast the headers to.

I keep getting different Exceptions as I change my code, like UnsupportedOperationException and java.lang.ClassCastException: java.util.Arrays$ArrayList incompatible with java.util.ArrayList, when I change the code to something else, trying out other StackOverflow solutions like this - Why do I get an UnsupportedOperationException when trying to remove an element from a List?.

I have just started working on Java and have been working more on python and nodejs in the past.

Any help is appreciated.

3
  • Try new ArrayList<String>(downloadRequest.getHeaders()) to convert it Commented Mar 4, 2021 at 16:45
  • @azro Yes that works, not getting an error with it, can accept it in some time Commented Mar 4, 2021 at 16:48
  • It's bad coding style to use a getter to update another object's collection field. You should create a clearHeaders() method instead. Commented Mar 4, 2021 at 16:52

3 Answers 3

4

The problem is that Collection#clear(), as mentioned in the docs is an optional operation and not all implementations need to support it. If they do not, they can throw UnsupportedOperationException. In your case, the list returned from downloadRequest.getHeaders() is apparently an unmodifiable collection which does not support this operation.

If it did, calling clear() on it would remove all headers from the downloadRequest. Is that what you're trying to achieve? Probably not. If yes, instead there should be a method like downloadRequest.clearHeaders().

To work around this problem, you can copy the elements out of an unmodifiable collection into e.g. an ArrayList:

new ArrayList<>(downloadRequest.getHeaders())

This copies the elements out of the original container into a new modifiable ArrayList that you can then modify however you like.


Also note you're mentioning java.util.Arrays$ArrayList which is named ArrayList, but it is not java.util.ArrayList. This is an unresizable collection returned from Arrays.asList(...) and it does not support clear() either.

Sign up to request clarification or add additional context in comments.

1 Comment

One last remark is that downloadRequest.getHeaders() should never return null in a good design. Methods returning null instead of an empty collection are a code smell and should only be used when null is different from an empty collection. (Actually in that case you're better of with some kind of a specialized class, but that's a different discussion.)
2

The downloadRequest.getHeaders() method may return a Collection that is read-only and so doesn't support .clear()

You may use an ArrayList to wrap it and get a write-accessible structure

// private list<String> headers;


Collection<String> headers = downloadRequest.getHeaders();
this.headers = headers  == null ? new ArrayList<>() : new ArrayList<>(headers) ;

Comments

0

I think you may be using the wrong ArrayList class when doing new ArrayList()

From your ClassCastException you are using : java.util.Arrays$ArrayList, which is a nested class of the Arrays class and is immutable.

Check your import : you should be using java.util.ArrayList.

Edit : never mind this nested class is private; previous answer is probably right, the collection returned must be immutable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.