Java Language 배열 생성 및 초기화


기본 케이스

int[]   numbers1 = new int[3];                 // Array for 3 int values, default value is 0
int[]   numbers2 = { 1, 2, 3 };                // Array literal of 3 int values
int[]   numbers3 = new int[] { 1, 2, 3 };      // Array of 3 int values initialized
int[][] numbers4 = { { 1, 2 }, { 3, 4, 5 } };  // Jagged array literal
int[][] numbers5 = new int[5][];               // Jagged array, one dimension 5 long
int[][] numbers6 = new int[5][4];              // Multidimensional array: 5x4

배열은 기본 또는 참조 형식을 사용하여 만들 수 있습니다.

float[]  boats = new float[5];          // Array of five 32-bit floating point numbers.
double[] header = new double[] { 4.56, 332.267, 7.0, 0.3367, 10.0 };
                                       // Array of five 64-bit floating point numbers.
String[] theory = new String[] { "a", "b", "c" };
                                       // Array of three strings (reference type).
Object[] dArt = new Object[] { new Object(), "We love Stack Overflow.", new Integer(3) };
                                       // Array of three Objects (reference type).

마지막 예에서는 선언 된 배열 유형의 하위 유형이 배열에 허용됩니다.

사용자 정의 유형에 대한 배열은 기본 유형과 유사하게 만들 수 있습니다.

UserDefinedClass[] udType = new UserDefinedClass[5];

배열, 컬렉션 및 스트림

Java SE 1.2
// Parameters require objects, not primitives

// Auto-boxing happening for int 127 here
Integer[]       initial        = { 127, Integer.valueOf( 42 ) };
List<Integer>   toList         = Arrays.asList( initial );  // Fixed size! 

// Note: Works with all collections
Integer[]       fromCollection = toList.toArray( new Integer[toList.size()] );

//Java doesn't allow you to create an array of a parameterized type
List<String>[]  list = new ArrayList<String>[2];  // Compilation error!
Java SE 8
// Streams - JDK 8+
Stream<Integer> toStream       = Arrays.stream( initial );
Integer[]       fromStream     = toStream.toArray( Integer[]::new );

소개

배열 은 고정 된 수의 원시 값 또는 객체 인스턴스에 대한 참조를 보유하는 데이터 구조입니다.

배열의 각 항목은 요소라고하며 각 요소는 숫자 인덱스로 액세스됩니다. 배열이 만들어지면 배열의 길이가 설정됩니다.

int size = 42;
int[] array = new int[size];

배열의 크기는 초기화 될 때 런타임에 고정됩니다. 초기화 후에는 변경할 수 없습니다. 런타임에 크기를 변경할 수 있어야하는 경우 ArrayList 와 같은 Collection 클래스를 대신 사용해야합니다. ArrayList 는 배열에 요소를 저장 하고 새 배열을 할당 하고 이전 배열의 요소를 복사 하여 크기 조정을 지원합니다.

배열이 원시적 형의 경우, 즉

int[] array1 = { 1,2,3 };
int[] array2 = new int[10];

값은 배열 자체에 저장됩니다. 위의 array2 같이 이니셜 라이저가없는 경우 각 요소에 할당 된 기본값은 0 입니다.

배열 형이 객체 참조 인 경우, 다음과 같이됩니다.

SomeClassOrInterface[] array = new SomeClassOrInterface[10];

배열에는 SomeClassOrInterface 유형의 객체에 대한 참조 가 포함됩니다. 이러한 참조의 예를 참조 할 수 SomeClassOrInterface 또는 (클래스) 또는 서브 클래스 (인터페이스) 구현 클래스 SomeClassOrInterface . 배열 선언에 초기자를 포함하지 않으면 null 의 기본값이 각 요소에 할당됩니다.

모든 배열이기 때문에 int -indexed, 배열의 크기는로 지정해야합니다 int . 배열의 크기는 long 으로 지정할 수 없습니다.

long size = 23L;
int[] array = new int[size]; // Compile-time error:
                             // incompatible types: possible lossy conversion from
                             // long to int

배열은 인덱스가 0 에서 시작하여 length - 1 끝점을 의미하는 0 부터 시작하는 인덱스 시스템을 사용합니다.

예를 들어 다음 이미지는 크기가 10 인 배열을 나타냅니다. 여기서 첫 번째 요소는 인덱스 1 있고 마지막 요소는 인덱스 10 (아래 그림 참조). 첫 번째 요소는 인덱스 0 있고 마지막 요소는 인덱스 9 에 있습니다.

10 요소의 배열

배열 요소에 대한 액세스는 일정한 시간 내에 수행됩니다. 즉, 배열의 첫 번째 요소에 액세스하는 것은 두 번째 요소, 세 번째 요소 등을 액세스하는 것과 동일한 비용 (시간상)을 갖는다는 것을 의미합니다.

Java는 리터럴생성자 표기법을 비롯하여 배열을 정의하고 초기화하는 여러 가지 방법을 제공합니다. new Type[length] 생성자를 사용하여 배열을 선언 할 때 각 요소는 다음 기본값으로 초기화됩니다.

원시 형 배열 만들기 및 초기화

int[] array1 = new int[] { 1, 2, 3 }; // Create an array with new operator and 
                                      // array initializer.
int[] array2 = { 1, 2, 3 };           // Shortcut syntax with array initializer.
int[] array3 = new int[3];            // Equivalent to { 0, 0, 0 }
int[] array4 = null;                  // The array itself is an object, so it
                                      // can be set as null.

배열을 선언 할 때 [] 는 선언의 시작 부분 (유형 이름 다음)이나 특정 변수 선언 자의 일부 (변수 이름 뒤에) 또는 둘 모두로 표시됩니다.

int array5[];       /* equivalent to */  int[] array5;
int a, b[], c[][];  /* equivalent to */  int a; int[] b; int[][] c;
int[] a, b[];       /* equivalent to */  int[] a; int[][] b;
int a, []b, c[][];  /* Compilation Error, because [] is not part of the type at beginning
                       of the declaration, rather it is before 'b'. */    
// The same rules apply when declaring a method that returns an array:
int foo()[] { ... } /* equivalent to */  int[] foo() { ... }

다음 예제에서 두 선언은 모두 정확하며 아무런 문제없이 컴파일하고 실행할 수 있습니다. 그러나 Java 코드 작성 규칙Google Java 스타일 가이드 는 변수 이름 다음에 대괄호가 있는 양식을 금지합니다 . 대괄호는 배열 유형을 식별하며 유형 지정과 함께 표시되어야합니다 . 메소드 반환 시그니처에도이 값을 사용해야합니다.

float array[]; /* and */ int foo()[] { ... } /* are discouraged */
float[] array; /* and */ int[] foo() { ... } /* are encouraged */

낙심 타입은 변수 이름 다음에 괄호가있는 C의 구문에 익숙한 C 사용자 전환을 수용 하기위한 것입니다.

Java에서는 크기가 0 배열을 가질 수 있습니다.

int[] array = new int[0]; // Compiles and runs fine.
int[] array2 = {};        // Equivalent syntax.

그러나 빈 배열이므로 요소를 읽거나 할당 할 수 없습니다.

array[0] = 1;     // Throws java.lang.ArrayIndexOutOfBoundsException.
int i = array2[0]; // Also throws ArrayIndexOutOfBoundsException.

이러한 빈 배열은 일반적으로 반환 값으로 유용하므로 호출 코드는 NullPointerException 유발할 수있는 잠재적 null 값 대신 배열을 처리하는 것에 대해서만 염려해야합니다.

배열의 길이는 음수가 아닌 정수 여야합니다.

int[] array = new int[-1]; // Throws java.lang.NegativeArraySizeException

배열 크기는 length 라는 public 최종 필드를 사용하여 결정할 수 있습니다.

System.out.println(array.length); // Prints 0 in this case.

참고 : array.length 는 값이 할당 된 배열 요소의 수를 반환하는 ArrayList.size() 와는 달리 배열의 실제 크기를 반환하고 값이 할당 된 배열 요소 수는 반환하지 않습니다.

다차원 배열 만들기 및 초기화

다차원 배열을 만드는 가장 간단한 방법은 다음과 같습니다.

int[][] a = new int[2][3];

a[0]a[1] 두 개의 3 길이 int 배열을 생성합니다. 이것은 직사각형 다차원 배열의 고전적인 C 스타일 초기화와 매우 유사합니다.

동시에 만들고 초기화 할 수 있습니다.

int[][] a = { {1, 2}, {3, 4}, {5, 6} };

직사각형 다차원 배열 만 지원되는 C와 달리 내부 배열은 길이가 같거나 정의 될 필요가 없습니다.

int[][] a = { {1}, {2, 3}, null };

여기서 a[0] 은 1 길이의 int 배열이며 a[1] 은 2 길이의 int 배열이고 a[2]null 입니다. 이와 같은 배열을 들쭉날쭉 한 배열 또는 불규칙한 배열 이라고 합니다 . 즉, 배열의 배열입니다. Java의 다차원 배열은 배열의 배열로 구현됩니다. 즉, array[i][j][k]((array[i])[j])[k] . C #과는 달리 구문 array[i,j] 는 Java에서 지원되지 않습니다.

Java의 다차원 배열 표현

Java 다차원 배열의 시각적 표현

출처 - Ideone에 게시

참조 유형 배열 만들기 및 초기화

String[] array6 = new String[] { "Laurel", "Hardy" }; // Create an array with new 
                                                      // operator and array initializer.
String[] array7 = { "Laurel", "Hardy" };              // Shortcut syntax with array 
                                                      // initializer.
String[] array8 = new String[3];                      // { null, null, null }
String[] array9 = null;                               // null

이데올로기에 살기

위에 표시된 String 리터럴 및 프리미티브 외에도 배열 초기화에 대한 단축키 구문은 표준 Object 유형에서도 작동합니다.

Object[] array10 = { new Object(), new Object() };

배열은 공변 (covariant)하기 때문에 요소를 String 아닌 다른 것으로 설정하려고하면 ArrayStoreException 이 throw되지만 참조 유형 배열을 하위 클래스의 배열로 초기화 할 수 있습니다.

Object[] array11 = new String[] { "foo", "bar", "baz" };
array11[1] = "qux"; // fine
array11[1] = new StringBuilder(); // throws ArrayStoreException

바로 가기 구문에 암시 적 Object[] 유형이 있으므로 바로 가기 구문을 사용할 수 없습니다.

배열은 String[] emptyArray = new String[0] 을 사용하여 0 요소로 초기화 할 수 있습니다. 예를 들어 길이가 0 Array 은 메서드에서 객체의 런타임 유형이 필요할 때 Collection 에서 Array만드는 데 사용됩니다.

기본 유형과 참조 유형 모두에서 빈 배열 초기화 (예 : String[] array8 = new String[3] )는 각 데이터 유형기본값으로 배열을 초기화합니다.

제네릭 형식 배열 만들기 및 초기화

제네릭 클래스에서는 제네릭 형식의 배열을 형식 지움 으로 인해 초기화 할 수 없습니다 .

public class MyGenericClass<T> {
    private T[] a;

    public MyGenericClass() {
        a = new T[5]; // Compile time error: generic array creation
    }
}

대신 다음 방법 중 하나를 사용하여 만들 수 있습니다 (이 옵션은 검사되지 않은 경고를 생성 함)

  1. Object 배열을 만들고이를 generic 형식으로 캐스팅합니다.

    a = (T[]) new Object[5];
    

    이것은 가장 간단한 방법이지만 기본 배열이 여전히 Object[] 유형 Object[] 메서드는 형식 안전을 제공하지 않습니다. 따라서 배열을 만드는이 방법은 공개적으로 노출되지 않는 제네릭 클래스 내에서만 사용하는 것이 가장 좋습니다.

  2. Array.newInstance 를 클래스 매개 변수와 함께 사용하여 :

    public MyGenericClass(Class<T> clazz) {
        a = (T[]) Array.newInstance(clazz, 5);
    }
    

    여기서 T 의 클래스는 생성자에 명시 적으로 전달되어야합니다. Array.newInstance 의 반환 유형은 항상 Object 입니다. 그러나 새로 생성 된 배열은 항상 T[] 유형이므로 안전하게 외부화 할 수 있으므로이 방법이 더 안전합니다.

초기화 후 배열 채우기

Java SE 1.2

Arrays.fill() 은 초기화 후에 동일한 값으로 배열을 채우기 위해 사용할 수 있습니다 :

Arrays.fill(array8, "abc");        // { "abc", "abc", "abc" }

이데올로기에 살기

fill() 은 배열의 지정된 범위에있는 각 요소에 값을 할당 할 수도 있습니다.

Arrays.fill(array8, 1, 2, "aaa");  // Placing "aaa" from index 1 to 2.

이데올로기에 살기

Java SE 8

Java 버전 8, setAll 및 그 Concurrent parallelSetAll 메소드를 사용하여 배열의 모든 요소를 ​​생성 된 값으로 설정할 수 있습니다. 이 메소드는 인덱스를 받아들이고 해당 위치에 원하는 값을 리턴하는 생성자 함수를 전달합니다.

다음 예제에서는 정수 배열을 만들고 해당 요소를 모두 해당 인덱스 값으로 설정합니다.

int[] array = new int[5];
Arrays.setAll(array, i -> i); // The array becomes { 0, 1, 2, 3, 4 }.

이데올로기에 살기

배열 선언과 초기화의 분리

배열 요소의 인덱스 값은 정수 (0, 1, 2, 3, 4, ...) 여야하며 배열의 길이보다 작아야합니다 (인덱스는 0부터 시작 함). 그렇지 않은 경우, ArrayIndexOutOfBoundsException 가 Throw됩니다.

int[] array9;             // Array declaration - uninitialized
array9 = new int[3];      // Initialize array  - { 0, 0, 0 }
array9[0] = 10;           // Set index 0 value - { 10, 0, 0 }
array9[1] = 20;           // Set index 1 value - { 10, 20, 0 }
array9[2] = 30;           // Set index 2 value - { 10, 20, 30 }

어레이 초기화 프로그램 바로 가기 구문을 사용하여 배열을 다시 초기화 할 수 없습니다.

배열 초기화자를 필드 선언이나 로컬 변수 선언에만 지정하거나 배열 작성 표현식의 일부로 지정할 수 있기 때문에 배열 초기화 자를 사용 하여 바로 가기 구문을 통해 배열을 다시 초기화 할 수 없습니다.

그러나 새 배열을 만들고 이전 배열을 참조하는 데 사용되는 변수에 할당 할 수 있습니다. 이로 인해 해당 변수가 참조하는 배열이 다시 초기화되는 동안 변수 내용은 완전히 새로운 배열입니다. 이렇게하려면 new 연산자를 배열 초기화 프로그램과 함께 사용할 수 있으며 배열 변수에 할당 할 수 있습니다.

// First initialization of array
int[] array = new int[] { 1, 2, 3 };

// Prints "1 2 3 ".
for (int i : array) {
    System.out.print(i + " ");
}

// Re-initializes array to a new int[] array.
array = new int[] { 4, 5, 6 };

// Prints "4 5 6 ".
for (int i : array) {
    System.out.print(i + " ");
}

array = { 1, 2, 3, 4 }; // Compile-time error! Can't re-initialize an array via shortcut 
                        // syntax with array initializer.

이데올로기에 살기