ArrayList의 초기 크기


257

다음을 수행하여 ArrayList의 초기 크기를 설정할 수 있습니다

ArrayList<Integer> arr=new ArrayList<Integer>(10);

그러나 할 수 없습니다

arr.add(5, 10);

범위를 벗어난 예외가 발생하기 때문입니다.

할당 한 공간에 액세스 할 수없는 경우 초기 크기 설정은 무엇입니까?

추가 기능은 add(int index, Object element)색인 10에 추가하지 않도록 정의됩니다 .


52
사실, 문서로부터 명확하지 목록은 적어도 가질 필요가 있다는 n 개의 항목이 당신이 할 수 전에 추가 set/add항목 N-1 .
인식

5
인식 : 나는 그것이 명백한 지 모르겠지만 그것이 명시되어 있습니다. Throws : IndexOutOfBoundsException-인덱스가 범위 외인 경우 (index <0 || index> = size ()).
Natix

3
흠, 생성자는 "지정된 초기 용량으로 빈 목록을 구성합니다."라고 말하고, 빈 목록의 개념을 취하면 색인 5는있을 수 없습니다. 그러나 이것이 처음에는 보이지 않을 것이라는 데 동의합니다 ...
quaylar

12
또한 배열을 특정 값으로 초기화하면 해당 값보다 낮은 인덱스를 사용할 수 있다고 가정 할 수 있습니다 ArrayList. 나는 개인적으로 특정 지수에 물건을 넣을 수있는 크기를 설정할 수있는 방법을 원합니다. 이 방법은 눈에 띄지 않는 것 같습니다.
Andrew Wyld

1
어떤 numbskull이 이런 식으로 컬렉션을 디자인 했습니까?! 이로 인해 가변 길이 요소 (예 : 각 배열의 길이가 다를 수있는 ArrayList <String []>)가있는 구조의 병렬 인스턴스화에 대한 중복 작업이 발생합니다. 메모리가 이미 할당되어 N 개의 요소를 추가 한 후에 목록을 재 할당 할 필요가없는 경우 해당 인덱스는 처음부터 직접 액세스 할 수 있어야합니다. C / C ++, C #, Objective C 및 Swift 이후 Oracle에서 아무도이 패턴을 배운 사람이 없습니까?!
patrickjp93

답변:


387

배열 목록의 크기와 용량을 혼동하고 있습니다.

  • 사이즈 리스트의 요소의 수이고;
  • 용량 리스트는 잠재적으로 그 내부 구조를 재 할당없이 수용 할 수있는 요소 수이다.

를 호출 new ArrayList<Integer>(10)하면 목록의 크기가 아니라 목록의 초기 용량을 설정하게됩니다 . 다시 말해서, 이런 식으로 구성되면, 배열리스트는 수명이 다 된 상태로 시작됩니다.

배열 목록에 10 개의 요소를 추가하는 한 가지 방법은 루프를 사용하는 것입니다.

for (int i = 0; i < 10; i++) {
  arr.add(0);
}

이 작업을 수행하면 인덱스 0..9에서 요소를 수정할 수 있습니다.


51
+1 : 더 짧은 루프입니다 while(arr.size() < 10) arr.add(0);. 크기가 최소한이어야 10합니다. 예를 들어 다음과 같이 사용할 수 있습니다arr.set(9, n);
Peter Lawrey

10
+1 : 훌륭한 반응입니다. 가능하다면 +10을 줄 것입니다. 단일 생성자 호출에서 초기 크기와 초기 용량을 모두 설정할 수없는 이유는 API에서 즉시 분명하지 않습니다. 당신은 일종의 api를 읽고 "아, ArrayList에는 그렇게 할 메소드 나 생성자가 없을 것"이라고 말해야합니다.
demongolem

@PeterLawrey 코드는 짧을 수 있지만 루프 반복마다 하나의 메서드가 아닌 두 개의 메서드 호출이 포함되어 있습니다.
neuralmer

@neuralmer size () 및 add ()가 인라인 될 것으로 예상하므로 런타임에 실제 메서드 호출이 발생하지 않습니다.
피터로 레이

109

미리 정의 된 크기의 목록을 원하는 경우 다음을 사용할 수도 있습니다.

List<Integer> arr = Arrays.asList(new Integer[10]);

11
여기에 약간의 단점이 있으며 결과 List는 null로 가득합니다. Guava를 사용하면 s로 Ints.asList(new int[10])목록을 초기화 할 수 있습니다 0. 예를 들어 깨끗한 패턴입니다.
dimo414

1
질문은 ArrayList <E>에 대해 이야기합니다. List <E>를 사용하고 있습니다. 아무도 이것을 관찰하지 않았다 ??? 게다가, 그들은이 무관 한 대답 을 찬성했습니다 ! 나는 결코하지 않기 때문에 당신의 대답을 downvote하지 않습니다. 간단히 ... Godssake!
Apostolos

3
@Apostolos ArrayListList인터페이스 의 구현 이며을 Arrays.asList반환합니다 ArrayList. 다형성을 찾아 보는 것이 좋습니다.
Liam Potter

그래도 고정 크기의 목록을 반환합니다. 더 많은 요소를 추가하려고 시도UnsupportedOperationException
Koray Tugay

47

Collections.fill (list, obj);를 사용하려면 반복되는 객체로 목록을 채우려면 대신 사용할 수 있습니다.

ArrayList<Integer> arr=new ArrayList<Integer>(Collections.nCopies(10, 0));

라인은 ArrayList에 10 번 0을 복사합니다.


20

의 용량sizeArrayList다릅니다 . 크기ArrayList(및 다른 요소에 포함 된 요소 수와 같습니다.List 구현)에 .

용량 internaly의 요소를 저장하는데 사용되는 기본 어레이의 단 길이 ArrayList, 항상 크거나 동일 사이즈 목록.

set(index, element)목록을 호출 할 때 index목록 요소의 실제 수 (= 크기)와 관련이 있습니다 (코드에서 0이므로AIOOBE 배열 길이 (= 용량) throw 됨)와 관련이 있습니다 (구현 세부 사항에 따라 다릅니다) ~로ArrayList ).

set방법은와 List같은 모든 구현에 공통적입니다 . 예를 들어 LinkedList실제로 배열에 의해 구현되지 않고 연결된 항목 체인으로 사용됩니다.

편집 : 실제로이 add(index, element)방법을 사용 set(index, element)하지는 않지만 원칙은 동일합니다.


10

index가있는 요소를 추가하려는 경우 대신 배열을 사용할 수 있습니다.

    String [] test = new String[length];
    test[0] = "add";

5
OP는 처음에는 배열이 아닌 목록을 사용하고 싶었습니다.
Stephan

9

10은 크기 (0)가 아니라 AL의 초기 용량입니다. 요소를 많이 추가 할 때는 초기 용량을 높은 값으로 언급해야합니다. 요소를 계속 추가 할 때 용량을 확장하는 오버 헤드가 발생하지 않기 때문입니다.


6

귀하의 질문에 대한 정확한 답변은 다음과 같습니다.

ArrayList에서 초기 크기를 설정하면 nr이 줄어 듭니다. 내부 메모리 재 할당이 자주 발생합니다. 리스트는 배열에 의해 지원됩니다. 예를 들어, 요소를 처음 삽입 할 때 초기 용량 0을 지정하면 내부 배열의 크기를 조정해야합니다. 목록에 보유 할 요소의 수를 대략적으로 알고 있다면 초기 용량을 설정하면 nr이 줄어 듭니다. 목록을 사용하는 동안 발생하는 메모리 재 할당 수


3

이것은 누군가를 도울 수 있습니다-

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));

3

늦었지만 Java 8 이후 에는 개인적으로 StreamAPI를 사용하는 다음과 같은 접근 방식이 더 간결하며 허용되는 답변 의 대안이 될 수 있습니다 .

예를 들어

Arrays.stream(new int[size]).boxed().collect(Collectors.toList())

여기서 size바람직한 List크기 는 여기언급 된 단점 없이 ,의 모든 요소는 다음 List과 같이 초기화됩니다 0.

(빠른 검색을 수행했지만 stream게시 된 답변에 표시되지 않습니다. 이 답변이 중복되어 있으면 제거 할 수 있는지 알려주십시오.)


1

현재 목록에 요소가 없으므로 목록의 색인 5에없는 요소는 추가 할 수 없습니다. 목록의 용량을 현재 크기와 혼동하고 있습니다.

그냥 전화하십시오 :

arr.add(10)

정수를 ArrayList에 추가하려면


1

arraylist의 용량은 10이지만 실제 목록에는 요소가 없습니다. add 메소드는 실제 목록에 요소를 삽입하는 데 사용됩니다. 요소가 없으므로 색인 5에 요소를 삽입 할 수 없습니다.


1

당신이 당신의 10 항목을 추가하려면 다음 ArrayList을 시도 할 수 있습니다

for (int i = 0; i < 10; i++)
    arr.add(i);

배열 크기 변수를 이미 선언 한 경우 size숫자 '10'대신 변수 를 사용합니다


1

비슷한 문제에 직면하여 arrayList가 List 인터페이스의 크기 조정 가능 배열 구현이라는 것을 알고 있으면 요소를 추가 할 수 있지만 최소한 초기 크기를 정의하는 옵션이 있어야합니다. 어쨌든 먼저 배열을 만들고 다음과 같은 목록으로 변환 할 수 있습니다.

  int index = 5;
  int size = 10;

  Integer[] array = new Integer[size];
  array[index] = value;
  ...
  List<Integer> list = Arrays.asList(array);

또는

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);

0

ArrayList myList = 새 ArrayList (10);

//  myList.add(3, "DDD");
//  myList.add(9, "III");
    myList.add(0, "AAA");
    myList.add(1, "BBB");

    for(String item:myList){
        System.out.println("inside list : "+item);
    }

/ * arraylist의 초기 용량은 내부적으로 이동 시간을 절약 할 뿐이라고 선언합니다. 내부적으로 요소를 추가 할 때 용량을 늘리기 위해 용량을 확인하면 처음에 0 인덱스에 1을 추가 한 후 요소를 추가 할 수 있습니다. * /


0

에 내 두 센트 Stream. 사용하는 것이 낫다고 생각합니다

IntStream.generate(i -> MyClass.contruct())
         .limit(INT_SIZE)
         .collect(Collectors.toList());

초기 값을 유연하게 입력 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.