jnk1m
Foliage IT
jnk1m
전체 방문자
오늘
어제
  • 분류 전체보기 (209)
    • Today I Learned (34)
    • Java (47)
    • Database (15)
    • [NHN Academy] (27)
    • Spring (47)
    • HTML + CSS + JavaScript (11)
    • JSP (3)
    • Node.js (10)
    • React Native (2)
    • 기타 (8)
    • 스크랩 (5)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
jnk1m

Foliage IT

[배열]
[NHN Academy]

[배열]

2022. 7. 14. 15:24

[배열 개요]

배열이란?

요소를 순서대로 모아서 관리하기 위한 시퀀스형 자료구조다.

 

배열은 요소를 순서대로 모아서 관리하기 위해 만들어진 자료구조

-배열의 모든 요소는 같은 타입을 가짐

-각각의 요소에는 정수 인덱스를 사용해서 액세스

-메서드를 만들 때 그 메서드가 반환하는 값을 가지고 배열을 만들도록 해도 됨 (가변 길이 배열)

 

배열은 고정 길이 레코드, 같은 타입의 데이터 묶음, 속도가 굉장히 빠르다. 

자바의 배열은 값 타입으로 가져옴. 정수형 인덱스를 가져와서 액세스한다. 

배열은 힙 영역의 주소값이 스택에 저장된다.

 

Java에서 배열 표기법

type[] name;

배열 변수 이름 / 배열의 차원/ 배열 변수 이름

 

배열의 차원

선형 1차원 배열과 표형 2차원 배열, 육면체형 3차원 배열 

 

 

2차원 배열

c,c++은 2차원 배열이 매트릭스 구조. 그래서 배열이 안된 부분이 들어가 있으면 안된다. 

[2][2],[2][1],[2][2] 불가능.

자바는 배열을 만들고 그 안에 배열을 또 만듦. 

 

[2][2],[2][1],[2][2] 가능.

 

배열 요소에 접근

각 배열에 대해 정수 인덱스가 제공됨

인덱스는 0에서 시작함 

 

배열의 경계 검사 

배열은 크기가 정해져 있어, 요소 액세스를 위해 배열 경계를 검사함

-배열 내 잘못된 위치에 대한 접근은 ArrayIndexOutOfBoundsException 예외를 발생

-length 변수 사용

2차원 배열의 경계 확인

for(int i=0; i<grid.length;i++){
	for(int j=0;j<grid[i].length;j++){
    	System.out.println(grid[i][j]);
       }
     }

배열과 컬렉션 비교

1. 배열 

-크기를 조절할 수 없음

-배열은 같은 타입의 요소를 저장하기 위한 자료구조

-배열의 요소는 읽기 전용 액세스 권한을 가질 수 없음

-일반적으로, 배열은 빠르지만 유연성이 떨어짐

 

2. 컬렉션

-ArrayList와 같은 컬렉션 클래스는 크기를 조절할 수 있음

-다양한 타입의 요소를 저장하기 위해 설계됨

-컬렉션의 요소는 읽기 전용이 가능

-컬렉션은 조금 느리지만 보다 유연함

 

배열의 경우 정렬하면 안에 있는 값을 바꾸지만 ArrayList는 정렬하면 포인터를 바꿈(C++)

 

 

[배열 생성]

 

배열 인스턴스 생성

배열 변수를 선언한다고 해서 배열이 생성되지 않음

-new 키워드를 사용해서 명시적으로 배열 인스턴스를 생성해야 함

-배열이 생성되면 기본값 0 (참조 타입인 경우 null)이 암시적으로 할당됨

 

 

배열 요소 복사

int[] i={1,2,3};
int[] j =i;

쉐도우 카피 : i[1]을 5로 바꾸면 j[1]도 바뀜. 딥 카피: 새 객체를 만들어서 배열 값을 복사해옴. 값을 전부 복사해오는 것. arrays.copy() 메서드 사용.

 

배열 사용

배열 메서드

int[] row = {1,2,3,4};
int[] row2 = row.clone();

Utilities.printArray(row);
Utilities.printArray(row2);

row[1]=5;

Utilities.printArray(row);
Utilities.printArray(row2);

내부적으로 딥카피를 하기 때문에 row2에 1번 인덱스에는 영향이 없다.

int[] array={3,4,5,6,4,3,5,5,4};
Arrays.sort(array);
Utilities.printArray(array);

정렬 메서드 사용

int index= Arrays.binarySeart(array,7) //하려면 반드시 정렬이 되어 있어야 함. 

배열에서 값 7이 있는 곳의 인덱스 번호를 알려줌

Arrays.fill(array,10);
Utilities.printArray(array);

foreach에서 배열을 사용할 수 있다. 사용할 수 있는 이터레이터.

스택 만들기

캡슐화를 생각하여 보여줄 것, 보여주지 않을 것을 생각하고 짤 것.

스택: pop, push.

스택을 쓸 수 있는 곳. 자료구조에 가서 그래프 탐색. 깊이 우선 탐색을 쓸 때 스택을 씀. 재귀함수 쓸 때, 문자 뒤질을 때, 익스플로러에서 뒤로가기 할때도 스택. 컨트롤 제트도 스택임.


public class IntStack {
    private int[] array = new int[2];
    int index =0;

    //파라미터 하나 들어오고 반환 값은 없다
    public void push(int input){ 
        array[index] = input; //하나 넣기
        index++; //다음 인덱스로 증가
    }

    //값을 외부로 반환해줘야 한다. 파라미터 필요없다. 
    public int pop(){  //푸시를 하면 0번 인덱스의 값은 1이 됨. ++해서 인덱스를 증가시켜주면 이제 가리키는 곳은 1번 인덱스. 팝은 인덱스가 가리키는 곳을 빼주려 하지만 현재 가리키는 곳의 값은 0...
        int output = array[--index]; //팝은 감소후연산으로 바꿔줘야함. 
        return output;// 팝을 하고 나서 값을 반환하기만 하고 삭제해줄 필요 없다. 어차피 다음
    }

    public int stackLength(){
        int length = array.length;
        return length;
    }

    public int getArray(int i){
        return array[i];
    }    
}
   
    class Test{
        public static void main(String[] args){
            try{
                IntStack stack = new IntStack();
                stack.push(1);
                stack.push(2);
                stack.push(3);
                System.out.println(stack.pop());
            

            //근데 스택은 안에 들어있는걸 다 보여줄 일이 없다.. 
            for(int i = 0; i < stack.stackLength();i++){ //제발 종료식에 i<, > 까먹지 말자.....
                System.out.println(stack.getArray(i)); //프라이빗이니까 게터
            }
        }
        catch(ArrayIndexOutOfBoundsException e){
            System.out.println("Index out of bounds");
        }
            
        }
    }

 

[실습]

파일은 1바이트가 8비트.

영문자 하나 계산하는데 1바이트.

파일 사이즈를 읽었는데 100바이트면 100글자임. 그럼 100개까지 배열로 만들어서 모음, 자음이 몇개냐 계산하는 프로그램을 짤거다.

 

스트림은 뭔가가 계속 들어오는 통로다. 스캐너도 스트림.

 

원시 타입의 데이터를 객체로 만들기 위해 wrapper 클래스를 이용. 

int -> Integer 

 

import java.io.*;

public class FileDetails {

    static void summerize(char[] contents){
        int vowel = 0, consonants=0, lines=0;
        for (char c:contents){
            if(Character.isLetter(c)){
                if("AEIOUaeiou".indexOf(c) != -1){
                    vowel++;
                }
                else{
                    consonants++;
                }
            }else if( c == '\n'){
                lines++;
            }
        }
        System.out.println("총 문자 수: "+contents.length);
        System.out.println("모음 수: "+vowel);
        System.out.println("자음 수: "+consonants);
        System.out.println("줄 수: "+lines);

    }
    public static void main(String[] args) {
        if(args.length != 1){
            System.out.println("Usage: java FileDetails FileName");
            return;
        }
        String fileName = args[0];

        // read the file that passed from parameter of main method
         File file = new File(fileName);
         try (FileInputStream stream = new FileInputStream(file)) { //tryWithResource 트라이문이 끝나면 자동으로 저 객체를 제거해줌. 클로즈가 구현됨.
            char[] contents = new char[(int)file.length()];
            for(int i =0;i<contents.length;i++){
                contents[i]=(char)stream.read(); //read()한글자씩 읽고 정수로 반환. 이걸 문자로 변환하여 넣는다. 
            }
            // for(char c:contents){
            //     System.out.print(c);
            // }
            summerize(contents);
         }
        catch (Exception e) {
             e.printStackTrace();
         }

         
    }
}

 

 

 

 

 

 

 

 

과제: 틱택토 게임 만들기

사용자 턴(x y)을 물어보고 좌표를 입력하라고 하면 0 1 하면 2차원 배열 0,1에 마크됨

그 담에 컴퓨터가 찍고

그담에 또 사람이 찍고.. 한줄이 완성되면 누가 승리했는지 

큐로 만들어봐도 괜찮음. 나중에 디큐를 할때 엠오디 연산을 해서 계산하는 연산을 써보는게..

    '[NHN Academy]' 카테고리의 다른 글
    • [참조 타입]
    • [객체 지향 프로그래밍]
    • Day3
    • Day2

    티스토리툴바