Подтвердить что ты не робот

Инициализация списка <T> с заданным числом нулей без цикла?

Можно ли инициализировать List<T>, чтобы содержать заданное число null s, где 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 (с предупреждением о немедленном бросании), но не с javac.


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

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

Ответ 1

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

ArrayList<T> myList = new ArrayList<T>(numEls);
Field f = ArrayList.class.getField("size");//cache this
f.setAccessible(true);
f.setInt(myList, numEls);

Ответ 2

Вам понадобится использовать отражение, чтобы создать экземпляр массива поддержки 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, которые оба используются здесь.

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

Ответ 3

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

final int maxSize = 50;

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

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

Ответ 4

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

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

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

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

Ответ 5

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

void fillNullList(List<T> list, count) {
   if (count > 0) {
       list.add(null);
       fillNullList(list, count - 1);
   }
}
Серьезно, почему вы хотите избежать цикла? Возможно, вам нужно решение с сложностью O (1), а не с решением сложности O (n), независимо от того, используется ли цикл для него.

Ответ 6

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

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

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

Ответ 7

Попробуйте следующее:

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();

Ответ 8

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

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

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