Инициализация списка <T>с заданным числом нулей без цикла? - PullRequest
16 голосов
/ 22 ноября 2011

Можно ли инициализировать List<T>, чтобы оно содержало заданное число null с, где T - параметр типа класса, членом которого является список? Я уверен, что могу сделать это с помощью цикла, но хотел бы знать, возможно ли это без.

List<T> myList = new ArrayList<T>(numEls);

создает список с заданной емкостью, но размером 0, поэтому myList.get(x) терпит неудачу для всех x, как и, например, myList.set(numEls-1,null).

myList = Arrays.asList(new T[numEls]);

не компилируется, а

 myList = (List<T>) Arrays.asList(new Object[numEls]);

компилируется в Eclipse (с предупреждением Unchecked cast), но не с javac.


Обновление: Спасибо за ответы! Однако я нашел другое, довольно короткое, решение, близкое к моей последней попытке выше, которое компилируется как в eclipse, так и с нашей автоматической системой сборки: Приведите массив, а не список!

myList = Arrays.asList((T[]) new Object[numEls]);

Ответы [ 9 ]

5 голосов
/ 22 ноября 2011

Вы должны использовать отражение, чтобы создать экземпляр резервного массива T[], используя Array.newInstance():

public static <T> List<T> getListWithNulls(Class<T> componentType, int length) {
   T[] array = (T[])Array.newInstance(componentType, length);
   return new ArrayList<T>(Arrays.asList(array));
}

Как видите, для этого требуется ссылка на Class<T> объект, представляющий тип T:

List<String> strListWithNulls = getListWithNulls(String.class, 100);

Также следите за тем, чтобы не перепутать классы java.lang.reflect.Array и java.util.Arrays, которые здесь используются.

Наконец, обратите внимание, чтоотражение будет намного медленнее, чем просто использование цикла.

4 голосов
/ 22 ноября 2011

То, что вы, вероятно, хотите, это что-то вроде этого ...

final int maxSize = 50;

List<T> v = new Vector<T>() {{setSize(maxSize);}};

Векторы позволяют установить размер, который заполняет их null.

3 голосов
/ 28 сентября 2012

Если вам не нужно изменять список ...

List<T> result = Collections.nCopies(num, (T) null);

... или поочередно

List<T> result = new ArrayList<T>(Collections.nCopies(num, (T) null));
2 голосов
/ 22 ноября 2011

Я бы просто использовал цикл, он проще и, скорее всего, будет быстрее.

List<T> list = 
while(list.size()<size) list.add(null);

Любой другой подход, который вы используете, скорее всего, будет использовать цикл для вас. Если это нормально, просто напишите свой собственный метод, который скрывает используемый цикл.

2 голосов
/ 22 ноября 2011

Не совсем решение, но вы хотели избежать цикла.

void fillNullList(List<T> list, count) {
   if (count > 0) {
       list.add(null);
       fillNullList(list, count - 1);
   }
}

Серьезно, почему вы хотите избежать цикла?Вероятно, вам нужно решение со сложностью O (1), а не решение со сложностью O (n), независимо от того, используется ли цикл для не.

1 голос
/ 14 августа 2018

новая опция с потоками:

Список resultColumn = IntStream.range (0, 10000) .mapToObj (i -> null) .collect (Collectors.toList ());

1 голос
/ 22 ноября 2011

если вы хотите ArrayList, вы можете использовать отражение, чтобы обмануть

ArrayList<T> myList = new ArrayList<T>(numEls);
Field f = ArrayList.class.getField("size");//cache this
f.setAccessible(true);
f.setInt(myList, numEls);
0 голосов
/ 06 апреля 2016

То, что я сделал, было

MyClass[] array = {new MyClass(), new MyClass(), new MyClass(), new MyClass(), new ProfileSectionDTO(), new MyClass()};
List<MyClass> MyClassList = Arrays.asList(array);

Грязно, но работает :)

0 голосов
/ 22 ноября 2011

Попробуйте это:

List<String> list = new ArrayList<String>(Arrays.asList(new String[100]));
for(String string : list){
    System.out.println(string);
}

Ну, вы можете написать иерархию:

class Base<T>{
    protected List<T> list; 

    public List<T> getList(){
       return list;
    }
}

class Child extends Base<String>{
    public Child(){
        list = new ArrayList<String>(Arrays.asList(new String[100]));
    }
}

Это можно использовать следующим образом:

Base<String> base = new Child();
base.getList();
...