배열이란?
- 자료를 순차적으로 관리하는 구조,배열
- 정수 20개를 이용한 프로그램을 할 때 20개의 정수 타입의 변수를 선언해야한다고 예시를 들면
- int num1,num2,num3,...,num20;
- 비효율적이고 변수 관리도 어려움
- 배열은 동일한 자료형의 변수를 한꺼번에 순차적으로 관리가 가능
- 자료가 연속으로 나열된 자료 구조.
- 배열의 길이는 length
- 데이터가 들어가는 정도가 size
- 배열에 대한 용어가 아님,ArrayList 등의 컬렉션 클래스 데이터 크기 나타내는 것
- 배열의 선언
- 배열의 크기가 몇 인지 선언해야 함.(fixed-length)
- 중간에 자료 빌 수 없음, 연속되는 자료
- 선언을 이미 했는데 공간이 부족하다면 새로운 배열을 만들어서 내용을 복사해야함.
- 자동으로 줄거나 늘지 않음
1) 자료형[] 배열이름 = new 자료형[개수];
ex) int[] arr = new int[10];
2) 자료형 배열이름[] = new 자료형[개수];
ex) int arr[] = new int[10];
- 배열의 메모리 구조
- 배열의 초기화
- 배열도 선언과 초기화를 동시에 할 수 있음
- 배열을 초기화 할 때는 개수를 명시하지 않음
- 배열의 선언과 초기화를 동시에 하는 경우 예시
// 배열의 초기화
int[] studentID1 = new int[] { 101, 102, 103 }; // 개수 생략
// int[] studentID2= new int[3] {101,102,103};//초기화 할떄 [] 안에 개수를 쓰면 오류가 발생함
// Cannot define dimension expressions when an array initializer is provided
// 오류 발생
int[] studentID3 = { 101, 102, 103 }; // new int[]부분을 생략
System.out.println(studentID1.length);// 결과:3
System.out.println(studentID3.length);// 결과:3
- 배열의 선언과 초기화를 동시에 하는 경우 new 자료형[] 부분을 생략할 수 있다.
- 배열을 초기화 하고 바로 값을 넣는 경우 자료형 [] 안에 배열 개수를 쓰면 Cannot define dimension expressions when an array initializer is provided 오류가 발생함
- 배열을 선언 후 초기화를 하는 경우 예시
// 배열 선언후 초기화
int[] studentID4;
studentID4 = new int[] { 101, 102, 103 };
// 선언 후 초기화 할떄는 new int[]를 생략할 수 없음
- 선언 후 초기화 할 때는 new 자료형[] 이 부분을 생략할 수 없다.
- 배열 선언 후 인덱스를 사용하여 배열에 값 넣기 예시
// 이미 생성된 배열에 값 넣기
int[] numbers3 = new int[3];
numbers3[0] = 1;
numbers3[1] = 2;
numbers3[2] = 3;
- 배열의 순서는 0 부터 시작
- 5개 길의의 배열을 만들었다면 0,1,2,3,4
- n개 길이의 배열을 만들었다면 0,1,2,3...,n-1
- 배열을 출력하는 법
// 배열을 출력하는 법
// System.out.println(배열이름); 으로 출력할 경우에는 주소값이 나옴
// 반복문을 활용하여 배열안에 요소들을 출력함
for (int i = 0; i < numbers3.length; i++) {
System.out.println(numbers3[i]);
- 배열은 반복문을 통하여 출력해야 한다.
- 선언만 하고 초기 화 하지 않을 경우
//정수형 배열에 선언 후 값을 안넣으면 default 값은 0
int[] integer = new int[3];
for (int i = 0; i < integer.length; i++) {
System.out.print(integer[i]+"/");
} //결과: 0/0/0/
System.out.println();
//실수형 배열에 선언 후 값을 안넣으면 default 값은 0.0
double[] double1 = new double[3];
for (int i = 0; i < double1.length; i++) {
System.out.print(double1[i]+"/");
} //결과:0.0/0.0/0.0/
System.out.println();
//객체 배열은 선언 후 값을 안넣으면 default 값은null
String [] stringTest= new String[3];
for (int i=0; i<stringTest.length;i++) {
System.out.print(stringTest[i]+"/");
}//결과: null/null/null/
- 배열의 자료형에 따라 정수는 0/ 실수는 0.0 객체 배열은 null 로 초기화됨
- 배열 사용하기
- []: 인덱스 혹은 첨자 연산자
- 배열의 위치를 지정하여 자료를 가져옴
- 모든 배열의 순서는 0부터 시작함
- n개 배열은 0부터 n-1 위치까지 자료가 존재
- 배열의 길이와 유효한 요소 값
- 배열의 길이의 속성:length
- 자료가 있는 요소만 출력하려면 크기에 대한 저장을 따로 해야함
double[] num1 = new double[5];
num1[0] = 10.0;
num1[1] = 20.0;
num1[2] = 30.0;
double total = 0.0;
for (int i = 0; i < num1.length; i++) {
total += num1[i];
}
System.out.println(total); // 결과:60.0
double total2 = 1.0;
for (int i = 0; i < num1.length; i++) {
total2 *= num1[i];
}
System.out.println(total2);// 결과:0.0;
// index가 3, 4 인 친구들이 0 으로 초기화 되어있기 때문에
// 유효한 숫자만큼만 계산하고 싶을때;
double[] num2 = new double[5];
int size = 0; // 유효한 값이 저장된 배열 요소 개수를 저장할 변수 선언
// 값을 저장한 후 size 변수 값 증가 시킴
num2[0] = 10.0;
size++;
num2[1] = 20.0;
size++;
num2[2] = 30.0;
size++;
double total3 = 1.0;
for (int i = 0; i < size; i++) {//유효한 값이 저장된 배열 요소 개수만큼 반복문 실행
total3 *= num2[i];
}
System.out.println(total3);//1.0*10.0*20.0*30.0 인 6000.0이 나오는 모습 확인 가능
- 배열에 알파벳 넣기
package array;
public class ArrayTest3 {
public static void main(String[] args) {
char[] alphabets=new char[26];
char ch='A';//65
for(int i=0;i<alphabets.length;i++){
alphabets[i]= ch;
ch++;
}
for(int i=0;i<alphabets.length;i++) {
System.out.println(alphabets[i]);
}
}
}
객체 배열 사용하기
- 참조 자료형을 선언하는 객체 배열
- 배열만 생성한 경우 요소는 null로 초기화 됨
- 각 요소를 new를 활용하여 생성하여 저장해야함
- 예시 책 객체 배열 만들기
package array;
public class Book {
private String bookName;
private String author;
public Book() {}//기본생성자
public Book(String bookName,String author) {//책의 이름과 저자를 매개변수로 갖는 생성자
this.bookName=bookName;
this.author=author;
}
//private으로 설정했기 때문에 외부에서 접근하기 위한 getter,setter 메서드 작성
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public void showBookInfo() {//책의 정보를 보여주는 메서드
System.out.println(bookName+","+author);
}
}
package array;
public class BookArray {
public static void main(String[] args) {
Book[] library = new Book[5];
for (int i = 0; i < library.length; i++) {
System.out.println(library[i]);
}//결과는 null 5개
// 책 5권이 만들어지는 것이 아닌, 책의 주소 5개가 만들어지는 것.
library[0] = new Book("태박산맥", "조정래");
library[1] = new Book("데미안", "헤르만 헤세");
library[2] = new Book("어떻게 살 것인가", "유시민");
library[3] = new Book("토지", "박경리");
library[4] = new Book("어린왕자", "생택쥐페리");
for (int i = 0; i < library.length; i++) {
library[i].showBookInfo(); //book 인스턴스 멤버들
}
for(int i=0;i<library.length;i++) {
System.out.println(library[i]); // book 인스턴스를 저장한 메모리 공간 주소
}
}
}
배열 복사하기
- 기존 배열과 같은 배열을 만들거나 배열이 꽉 찬 경우 더 큰 배열을 만들고 기존 배열 자료를 복사 할 수 있음
- System.arraycopy(src,srcPos,dest,destPos,length);
매개변수 | 설명 |
src | 복사할 배열이름 |
srcPos | 복사할 배열의 첫 번쨰 위치 |
dest | 복사해서 붙여 넣을 대상 배열 이름 |
destPos | 복사해서 대상 배열에 붙여 넣기를 시작할 첫번째 위치 |
length | src에서 dest로 자료를 복사할 요소 개수 |
- 배열 복사 예시
package array;
public class ArrayCopy {
public static void main(String[] args) {
int[] array1= {10,20,30,40,50};
int[] array2= {1,2,3,4,5};
System.arraycopy(array1, 0, array2, 1, 4);
for(int i =0; i<array2.length;i++) {
System.out.print(array2[i]+"/");//결과:1/10/20/30/40
}
}
}
- 객체 배열 복사 예시
package array;
public class ObjectCopy1 {
public static void main(String[] args) {
Book[] bookArray1 = new Book[3];
Book[] bookArray2 = new Book[3];
bookArray1[0]= new Book("태백산맥","조정래");
bookArray1[1]= new Book("데미안","헤르만 헤세");
bookArray1[2]= new Book("어떻게 살 것인가","유시민");
System.arraycopy(bookArray1, 0, bookArray2, 0, 3);
//bookArray1의 [0](첫번째 index0)부터 bookArray2에 [0](첫번째 index)에 3(지정한 갯수)만큼
//복사함.
for(int i =0; i<bookArray2.length;i++) {
bookArray2[i].showBookInfo();
}
}
}
- 얕은 복사: 배열 요소의 주소만 복사 되므로 배열 요소가 변경되면 복사된 배열의 값도 변경 됨.
package array;
public class ObjectCopy2 {
public static void main(String[] args) {
Book[] bookArray1 = new Book[3];
Book[] bookArray2 = new Book[3];
bookArray1[0] = new Book("태백산맥", "조정래");
bookArray1[1] = new Book("데미안", "헤르만 헤세");
bookArray1[2] = new Book("어떻게 살 것인가", "유시민");
System.arraycopy(bookArray1, 0, bookArray2, 0, 3);
for (int i = 0; i < bookArray2.length; i++) {
bookArray2[i].showBookInfo();
} // 결과: 위에 3권
bookArray1[0].setBookName("나목");
bookArray1[0].setAuthor("박완서");
System.out.println("=======bookArray1=======");
for (int i = 0; i < bookArray1.length; i++) {
bookArray1[i].showBookInfo();
}
System.out.println("=======bookArray2=======");
for (int i = 0; i < bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
// 값을 변경한 것은 bookArray1 이지만 bookArray2의 값도 변경됨//변경사항이 반영됨
/* 결과:
* 태백산맥,조정래
* 데미안,헤르만 헤세
* 어떻게 살 것인가,유시민
* =======bookArray1=======
* 나목,박완서
* 데미안,헤르만 헤세
* 어떻게 살 것인가,유시민
* =======bookArray2=======
* 나목,박완서
* 데미안,헤르만 헤세
* 어떻게 살 것인가,유시민
*/
}
}
- 객체 배열의 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스의 주소 값이기 떄문
- 객체 배열을 복사 할 때 인스턴스를 따로 생성하는 게 아니라 기존 인스턴스의 주소값만 복사
- 결국 두 배열의 서로 다른 요소가 같은 인스턴스를 가리키고 있으므로 복사되는 배열의 인스턴스 값이 변경되면 두 배열 모두 영향을 받음.
- 깊은 복사
- System.arraycopy()메서드를 사용하든 반복문을 사용하든 객체 배열을 복사하면 항상 인스턴스 주소가 복사
- 직접 인스턴스를 만들고 그 값을 복사 해야함
package array;
public class ObjectCopy3 {
public static void main(String[] args) {
Book[] bookArray1 = new Book[3];
Book[] bookArray2 = new Book[3];
bookArray1[0] = new Book("태백산맥", "조정래");
bookArray1[1] = new Book("데미안", "헤르만 헤세");
bookArray1[2] = new Book("어떻게 살 것인가", "유시민");
// 디폴드 생성자로 bookArray2 배열 인스턴스 생성
bookArray2[0] = new Book();
bookArray2[1] = new Book();
bookArray2[2] = new Book();
// bookArray1 배열 요소를 새로 생성한 bookArray2 배열 인스턴스에 복사
for (int i = 0; i < bookArray1.length; i++) {
bookArray2[i].setBookName(bookArray1[i].getBookName());
bookArray2[i].setAuthor(bookArray1[i].getAuthor());
}
for (int i = 0; i < bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
// 복사 후 배열2 요소 값 출력
bookArray1[0].setBookName("나목");
bookArray1[0].setAuthor("박완서");
System.out.println("=======bookArray1=======");
for (int i = 0; i < bookArray1.length; i++) {
bookArray1[i].showBookInfo();
}
System.out.println("=======bookArray2=======");
for (int i = 0; i < bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
/*
태백산맥,조정래
데미안,헤르만 헤세
어떻게 살 것인가,유시민
=======bookArray1=======
나목,박완서
데미안,헤르만 헤세
어떻게 살 것인가,유시민
=======bookArray2=======
태백산맥,조정래
데미안,헤르만 헤세
*/
}
}
public static void main(String[] args) {
Book[] bookArray1 = new Book[3];
Book[] bookArray2 = new Book[3];
bookArray1[0] = new Book("태백산맥", "조정래");
bookArray1[1] = new Book("데미안", "헤르만 헤세");
bookArray1[2] = new Book("어떻게 살 것인가", "유시민");
// 깊은 복사를 수행하여 bookArray2에 복사
for (int i = 0; i < bookArray1.length; i++) {
bookArray2[i] = new Book(bookArray1[i].getBookName(), bookArray1[i].getAuthor());
}
// bookArray2 출력
for (int i = 0; i < bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
// bookArray1의 첫 번째 요소를 변경
bookArray1[0].setBookName("나목");
bookArray1[0].setAuthor("박완서");
// bookArray1 출력
System.out.println("=======bookArray1=======");
for (int i = 0; i < bookArray1.length; i++) {
bookArray1[i].showBookInfo();
}
// bookArray2 출력
System.out.println("=======bookArray2=======");
for (int i = 0; i < bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
}
}
두 가지다 깊은 복사, 차이는 반복문으로 bookArray2배열 인스턴스 생성하면서 바로 넣느냐 아니면 생성 후 넣느냐 차이
향상된 for 문
- java 5부터 제공됨
- 처음에서 끝까지 모든 요소를 참조할 때 사용하면 편리한 반복문
- 향상된 for 문은 배열 요소값을 순서대로 하나씩 가져와서 변수에 대입
- 따로 초기화와 종료 조건이 없기 떄문에 모든 배열의 시작 요소부터 끝요소까지 실행
for(변수:배열){
반복 실행문;
}
package array;
public class EnhancedForLoop {
public static void main(String[] args) {
String[] strArray= {"Java","Android","C","JavaScript","Python"};
for(String lang:strArray) {
System.out.println(lang);
}
}
}
- 다차원 배열
- 2차원 이상의 배열
- -지도, 게임, 등 평면이나 공간을 구현 할 때 많이 사용 됨
- 이차원 배열의 선언과 구조
자료형[][] 배열 이름 = new 자료형[행개수][열개수];
ex) int[][] arr = new int[2][3]
위에 선언한 배열의 구조는아래와 같음
arr[0][0] | arr[0][1] | arr[0][2] |
arr[1][0] | arr[1][1] | arr[1][2] |
선언과 초기화
int[][] arr ={{1,2,3},{4,5,6}};
1 | 2 | 3 |
4 | 5 | 6 |
이차원 배열 사용하기
전체 모든 요소를 출력하려면 중첨된 for 문을 사용해야 함.
package array;
public class TwoDimension {
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
for(int i = 0;i<arr.length;i++) {
for(int j=0;j<arr[i].length;j++) {
System.out.println(arr[i][j]);
}
System.out.println();
}
}
}
arr[i]length: 열의 길이
arr.length: 행의 길이
package array;
public class TwoDimension2 {
public static void main(String[] args) {
int[][] arr= new int[2][3];
for(int i=0; i<arr.length;i++) {
for(int j=0;j<arr[0].length;j++) {
System.out.println(arr[i][j]);
}
System.out.println();
}
System.out.println(arr.length);
System.out.println(arr[0].length);
}
}
ArrayList 클래스
- 기존 배열은 길이를 정하여 선언하므로 사용 중 부족한 경우 다른 배열로 복사하는 코드를 직접 구현해야 함.
- 중간의 요소가 삭제되거나 삽입 되는 경우도 나머지 요소에 대한 조정하는 코드를 구현해야 함.
- ArrayList클래스는 자바에서 제공되는 객체 배열이 구현된 클래스
- 여러메서드와 속성 등 사용하여 객체 배열을 편리하게 관리할 수 있음
- 가장 많이 사용하는 객체 배열 클래스
메서드 | 설명 |
boolean add(E e) | 요소 하나를 배열에 추가 E는 요소의 자료형을 의미 |
int size() | 배열에 추가된 요소 전체 개수를 반환 |
E get(int index) | 배열의 index위치에 있는 요소 값을 반환 |
E remove(int index) | 배열의 index위치에 있는 요소 값을 제거하고, 그 값을 반환 |
boolean isEmpty() | 배열이 비어있는지 확인 |
요소를 추가하거나 제거 할 때 각 내부에서 코드가 모두 구현되어 있으므로 배열을 직접 선언하여 사용하는 것보다 편리
ArrayList에 가져다놓고 F1 키누르면 설명서나옴
- Module java.base 밑에 Package java.util 밑에 Class ArrayList<E> 가 있음
- java.lang.Object 밑에 java.util.AbstractCollection<E> 밑에 java.util.AbsractList<E> 밑에 java.util.ArrayList<E> 가 상속받아 생성되어 있음
- E는 이 리스트안에 있는 요소들의 타입을 적으면 됨.
아래로 내려가면 method 들이 있음
- 이름,매개변수,return 타입, 어떤 기능인지 확인하여 사용
ArrayList의 기본형식
ArrayList<E> 배열 이름 = new ArrayList<E>();
<E> 는 제너릭타입
E 에 어떤 객체 타입을 쓸건지 넣는 것
package arraylist;
import java.util.ArrayList;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(); //
list.add("aaa");
list.add("bbb");
list.add("ccc");
for(String s: list) {
System.out.println(s);
}
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
//list[i] 는 안됨 arrayList에서는 인덱스 연산자 기능을 제공하지 않음
}
}
}
어떤 타입으로 쓸지 명시하지 않고 쓰는 경우도 있음
package arraylist;
import java.util.ArrayList;
public class ArrayListTest2 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (Object obj : list) {
String s = (String) obj;
System.out.println(s);
}
// ArrayList에 요소를 추가할 때 제네릭을 사용하지 않으면
//기본적으로 Object 형태로 저장, 따라서 향상된 for문에서 요소를
// 순회할 때 Object 형태로 가져오게 됨
//그 후에 각 요소를 String으로 캐스팅하여 사용하는 것이 올바른 접근
for (int i = 0; i < list.size(); i++) {
String s = (String) list.get(i);
}
// 명시하지 않으면 object로 꺼내오기떄문에 명시적 형변환을 해야함
}
}
그렇지만 명시하고 쓰는 걸 추천.
ArrayList클래스 사용하여 응용프로그램 만들기
학생 성적 출력 프로그램
1. 과목 클래스 구현
package arraylist;
public class Subject {
private String name;
private int scorePoint;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScorePoint() {
return scorePoint;
}
public void setScorePoint(int scorePoint) {
this.scorePoint = scorePoint;
}
}
2. 학생 클래스 구현
package arraylist;
import java.util.ArrayList; //eclipse는 ctrl+shift+o 를 누르면 자동임포트해줌.
public class Student {
private int studentID;
private String studentName;
private ArrayList<Subject> subjectList;
// 다양한 과목을 수강 할 수 있기 때문에 과목은 배열로 관리
public Student(int studentID, String studentName) {
this.studentID = studentID;
this.studentName = studentName;
subjectList = new ArrayList<Subject>();
}
public void addSubject(String name,int score) {
Subject subject = new Subject();
subject.setName(name);
subject.setScorePoint(score);
subjectList.add(subject);
}
public void showStudentInfo() {
int total=0;
for (Subject subject: subjectList) {
total+=subject.getScorePoint();
System.out.println(studentName +"님의" +subject.getName()+
"과목의 성적은 "+subject.getScorePoint()+"점 입니다.");
}
System.out.println("총점은 "+ total);
}
}
3. 실행
package arraylist;
public class StudentTest {
public static void main(String[] args) {
Student studentLee = new Student(1001,"Lee");
studentLee.addSubject("국어", 100);
studentLee.addSubject("수학", 90);
studentLee.showStudentInfo();
Student studentKim = new Student(1002,"Kim");
studentKim.addSubject("국어", 70);
studentKim.addSubject("수학", 70);
studentKim.showStudentInfo();
}
}
'Java > Doit!자바프로그래밍입문_개념정리' 카테고리의 다른 글
Java 입문 기초 정리_ 추상 클래스 (0) | 2024.05.07 |
---|---|
Java 입문 기초 정리_상속과 다형성 (0) | 2024.05.03 |
Java 입문 기초 정리_ 클래스와 객체 1 (0) | 2024.04.29 |
Java 입문 기초 정리용_제어흐름 이해하기 (0) | 2024.04.26 |
Java 입문 기초 정리용_자바의 여러 가지 연산자 (0) | 2024.04.25 |