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());
0-9 это String
List<String> someList = Arrays.asList(getFromString.split("[\n·]"));
После удаления несуществующего элемента из списка возвращает null
, но я выбираю существующий элемент.
Если кто сталкивался с такой проблемой, дайте знать.
Ответы (2 шт):
Решил проблему.
Arrays.asList()
создает список без возможности изменять его, пришлось создавать отдельный объект ArrayList и вручную складывать значения:
List<String> listOfSaleString = new ArrayList<String>();
String[] listOfString = getStringFromAttr.split("[\n·]");
for(String loopValue: listOfString){
listOfSaleString.add(loopValue);
}
Ответ нашел здесь.
Во-первых, проблема, описанная в данном вопросе, НЕ существует, о чём я указал в комментарии:
Проблема не воспроизводится в том виде, как вы её описали: после удаления не существующего элемента из списка возвращает 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
.