Ответ 1
если вы хотите ArrayList
, вы можете использовать отражение для обмана
ArrayList<T> myList = new ArrayList<T>(numEls);
Field f = ArrayList.class.getField("size");//cache this
f.setAccessible(true);
f.setInt(myList, numEls);
Можно ли инициализировать 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]);
если вы хотите ArrayList
, вы можете использовать отражение для обмана
ArrayList<T> myList = new ArrayList<T>(numEls);
Field f = ArrayList.class.getField("size");//cache this
f.setAccessible(true);
f.setInt(myList, numEls);
Вам понадобится использовать отражение, чтобы создать экземпляр массива поддержки 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
, которые оба используются здесь.
Наконец, обратите внимание, что отражение будет намного медленнее, чем просто использование цикла.
То, что вы, вероятно, хотите, это что-то вроде этого....
final int maxSize = 50;
List<T> v = new Vector<T>() {{setSize(maxSize);}};
Векторы позволяют задать размер, который заполняет их null
.
Если вам не нужно мутировать список...
List<T> result = Collections.nCopies(num, (T) null);
... или поочередно
List<T> result = new ArrayList<T>(Collections.nCopies(num, (T) null));
На самом деле это не решение, но вы хотели избежать цикла.
void fillNullList(List<T> list, count) {
if (count > 0) {
list.add(null);
fillNullList(list, count - 1);
}
}
Серьезно, почему вы хотите избежать цикла? Возможно, вам нужно решение с сложностью O (1), а не с решением сложности O (n), независимо от того, используется ли цикл для него. Я бы просто использовал цикл, более простой и, скорее всего, быстрее.
List<T> list =
while(list.size()<size) list.add(null);
Любой другой подход, который вы используете, скорее всего, использует цикл для вас. Если это нормально, просто напишите свой собственный метод, который скрывает используемый цикл.
Попробуйте следующее:
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();
То, что я сделал, было
MyClass[] array = {new MyClass(), new MyClass(), new MyClass(), new MyClass(), new ProfileSectionDTO(), new MyClass()};
List<MyClass> MyClassList = Arrays.asList(array);
Грязный, но работает:)