java SE 17 arraylist возвращает null после удаления элемента по индексу

Элементов в списке 153: от 0 до 152, удаляю из этого списка элемент под любым индексом (в диапазоне от 0 до 152), после весь список возвращает null.

//извлекаю из String список ArrayList
List<String> listOfSaleString = Arrays.asList(getStringFromAttr.split("[\n·]"));

//вытаскиваю один элемент под индексом 1
String testGetElem = listOfSaleString.get(1);

//вывожу на экран, скрин от CMD ниже
System.out.println(testGetElem);
System.out.println(testGetElem.getClass());
System.out.println(listOfSaleString.getClass());
System.out.println("size of list: "+listOfSaleString.size());

//удаляю элемент по индексу 1 ()
listOfSaleString.remove(1);

//после возвращает null вместо списка
System.out.println("size of list: "+listOfSaleString.size());
System.out.println(listOfSaleString.getClass());

CMD

0-9 это String

List<String> someList = Arrays.asList(getFromString.split("[\n·]"));

После удаления несуществующего элемента из списка возвращает null, но я выбираю существующий элемент.

Если кто сталкивался с такой проблемой, дайте знать.


Ответы (2 шт):

Автор решения: Rodion

Решил проблему.

Arrays.asList()

создает список без возможности изменять его, пришлось создавать отдельный объект ArrayList и вручную складывать значения:

List<String> listOfSaleString = new ArrayList<String>();

String[] listOfString = getStringFromAttr.split("[\n·]");
for(String loopValue: listOfString){
    listOfSaleString.add(loopValue);
}

Ответ нашел здесь.

→ Ссылка
Автор решения: Nowhere Man

Во-первых, проблема, описанная в данном вопросе, НЕ существует, о чём я указал в комментарии:

Проблема не воспроизводится в том виде, как вы её описали: после удаления не существующего элемента из списка возвращает null. Если список создан при помощи Arrays.asList, его размер изменить нельзя, и при вызове listOfSaleString.remove(1) будет просто выброшено исключение java.lang.UnsupportedOperationException.

Во-вторых, скриншот, представленный в вопросе, на котором выводится некоторое null значение, НЕ соответствует коду -- на скриншоте 5 (пять) строк, а в коде 6 (шесть!) вызовов System.out.println, причём нет ни одной строки, которая могла бы вывести null; зато в выводе должна была повторяться строка, начинающаяся на "size of list: ".


Если реальная проблема заключалась в том, чтобы создать модифицируемый список из массива неких объектов (в данном случае строк), т.е. преобразовать массив в список, то для её решения существуют следующие стандартные способы, не требующие поэлементного добавления в цикле:

1. Вызов конструктора для соответствующей реализации списка ArrayList(Collection<? extends E> collection)
(аналогично для других реализаций интерфейса List таких как LinkedList, CopyOnWriteArrayList или классических/устаревших Vector/Stack):

// Java 7+: diamond operator
List<String> listJava7 = new ArrayList<>(Arrays.asList(getStringFromAttr.split("[\n·]")));
// Java 10+: var + List.of вместо Arrays.asList
var listJava10 = new ArrayList<>(List.of(getStringFromAttr.split("[\n·]")));

Основной "плюс" данного способа -- "однострочное" решение.

2. Вызов метода List::addAll для созданного экземпляра списка:

var list = new ArrayList<>();
list.addAll(Arrays.asList(getStringFromAttr.split("[\n·]")));

3. Вызов метода Collections.addAll(Collection<? super T> c, T... elements)
Здесь не потребуется оборачивать массив в промежуточный список, как в предыдущих двух способах.

// Java 5+
List<String> listJava5 = new ArrayList<String>();
Collections.addAll(listJava5, getStringFromAttr.split("[\n·]"));
// можно добавлять элементы по одному и более
Collections.addAll(listJava5, "foo");
Collections.addAll(listJava5, "bar", "baz", "qux");

Также в документации указано, что в большинстве реализаций этот способ значительно быстрее, чем вышеупомянутый List::addAll:

The behavior of this convenience method is identical to that of c.addAll(Arrays.asList(elements)), but this method is likely to run significantly faster under most implementations.

4. Вызов методов Collectors.toList() или Collectors.toCollection(Supplier<C> collectionFactory) при использовании Stream API

// Java 8+
var arrayList = Arrays.stream(str.split("\\s+")).collect(Collectors.toList());
var linkedList = Arrays.stream(str.split("\\s+")).collect(Collectors.toCollection(LinkedList::new));

Данный способ предпочтительнее, если ко входному массиву элементов нужно применить какие-то дополнительные операции, например, отфильтровать, отсортировать, преобразовать в другой тип и т.д.

Замечание: В документации указано, что метод Collectors.toList() НЕ гарантирует тип, мутабельность, сериализуемость или потокобезопасность возвращаемого списка, но по факту в основных реализациях JDK/JVM он возвращает экземпляр именно java.util.ArrayList.

→ Ссылка