본문 바로가기

항해99

[항해99] 자바 문법 종합반 2주차 ( 02.06 ~ 02.07 )

  • 비교연산자와 논리연산자
[ 산술연산자 : +, -, *, /, %(나머지), <<, >> ]
[ 비교연산자 : >, <, >=, <= , ==, != ]

System.out.println(10 != 10); // 10이 10이 아니니?F

[ 논리연산자 : &&(그리고), ||(비교), !(not) ]

	// 1. 피연산자가 모두 true이면 true => 그리고 (AND : &&)
        System.out.println("------------------");
        System.out.println( flag1 && flag2); // true
        System.out.println(flag1 && flag2 && flag3); // false
        
	// 2. 피연산자 중 하나라도 true 면 true => 또는(OR : ||)
        System.out.println("------------------");
        System.out.println(flag1 || flag2); // true
        System.out.println(flag1 || flag2 || flag3); // true
        
	// 3. AND
    	System.out.println("AND---------------");
    	System.out.println((5 > 3) && (3 > 1)); // true && true => true
    	System.out.println((5 > 3) && (3 < 1)); // true && false -> false

[ 대입연산자 : =, ++, -- ]
[ 기타연산자 : (type), ?, :, instance of ]

        // 1. 형변환 연산자
        int number = 93 + (int)98.8; // 93 + 98
        System.out.println(number);

        double doublenumber = (double)93 + 98.8; // 93.0 + 98.8
        System.out.println(doublenumber);
        
        // 2. 삼항 연산자
        // 비교연산자와 항상 함께 쓰임
        // 비교연산자의 결과 : true or false -> 이 결과의 값에 따라 결정되는 무언가!
        // 조건 ? 참 : 거짓
        int x =1;
        int y=9;

        boolean b = (x == y) ? true : false;
        System.out.println(b);

        // x랑 y랑 다르니?
        String s = (x != y) ? "정답" : "오답";
        System.out.println(s);

        // x가 y보다 큰 경우, x를 max에 넣어주고 작다면 y에 넣어줘
        int max = (x>y) ? x : y;
        System.out.println(max); // 9

        int min = (x<y) ? x : y;
        System.out.println(min);

        // 3. instance of
        // 피연산자가 조건에 명시된 클래스의 객체인지 비교하여
        // 맞으면 -> true
        // 틀리면 -> false
  • 연산자 우선 순위
[연산자 우선 순위 : 산술(+,-) > 비교(>, <=) > 논리(&&, ||) > 대입(++, --)]
- 연산자 여려개가 함께 있는 연산을 계산할때는 운선순위가 있음
- 위 우선순위에 따라서 최종적인 응답값이 결정됨
- 단, 괄호로 감싸주면 괄호안의 연산이 최우선순위로 계산
  • 산술 변환
- 두 피연산자의 타입을 같게 일치시킴 (둘 중에 저장공간 크기가 더 큰 타입으로 일치)
    - 피연산자의 타입이 'int' 보다 작은 'short' 타입이면 'long'으로 변환
    - 피연산자의 타입이 'long' 보다 작은 'int', 'short' 타입이면 'long'으로 변환
    - 피연산자의 타입이 'float' 보다 작은 'long', 'int', 'short' 타입이면 'float'로 변환
    - 피연산자의 타입이 'double' 보다 작은 'float', 'long', 'int', 'short' 타입이면 'double'로 변환
  -> 이처럼, 변수 여러개를 연산했을 때 결과값은 피연산자 중 표현 범위가 가장 큰 변수 타입을 가지게 됨
  • 비트 연산
- 비트 연산
  - Byte 를 8등분 한게 Bit
  - Bit 는 0, 1 둘 중 하나의 값만 저장하는 컴퓨터가 저장(표현) 가능한 가장 작은 단위
  - 컴퓨터의 가장 작은 단위가 8Bit 이기 때문에, 연산중에서 Bit 연산이 제일 빠름
  - 물론이전에 배운대로 0, 1 값으로 산술연산을 하거나, 비교연산을 할 수 있지만, 비트 연산을 통해 자리수를 옮길 수 도 있음
  - Bit의 자리수를 옮기는 것 : 비트 연산
  - '<<'(왼쪽으로 자리수 옮기기), '>>'(오른쪽으로 자리수 옮기기)
  - 0, 1 은 2진수 값이기 때문에
      - 자리수를 왼쪽으로 옮기는 횟수만큼 2의 배수로 곱셈이 연산되는 것과 같음 ( 0101(5) -> 1010(10) )
      - 자리수를 오른쪽으로 옮기는 횟수만큼 2의 배수로 나눗셈이 연산되는 것과 같음 ( 1010(10) -> 0101(5) )

 

  • 조건문

- 특정 조건 -> 조건문 (~으면)

- 특정 조건 + 반복 -> 반목문(~까지)

 

1.  if문

- 복합조건 OK : 괄호 안에 여러개 지정해 조건문 수행 가능

- 코드 중복 많음

 

2. Switch문 (+case)

- if문 보다 조건(가독성)이 좋음

- break 신경쓰기

- defaul (=else)

- 코드 중복 적음

 

3. if문으로 가위바위보 게임 만들기

- 두 개의 값을 비교하는 메소드 : Objexts.equals(좌, 우)

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // A에게 값 입력 받기
        System.out.println("A 입력 : ");
        String aHand = sc.nextLine();

        // B에게 값 입력 받기
        System.out.println("B 입력 : ");
        String bHand = sc.nextLine();

        // 두 개의 값을 비교하는 메서드 -> Objexts.equals(좌, 우)
        if (Objects.equals(aHand, "가위")) { // 값을 비교하는 Obects.equals() 메서드 사용
            if (Objects.equals(bHand, "가위")) {
                System.out.println("A 와 B 는 비겼습니다."); // A 와 B 의 입력값을 비교해서 결과 출력
            } else if (Objects.equals(bHand, "바위")) {
                System.out.println("B 가 이겼습니다.");
            } else if (Objects.equals(bHand, "보")) {
                System.out.println("A 가 이겼습니다.");
            } else {
                System.out.println(" B 유저 값을 잘못 입력하셨습니다.");
            }
        } else if (Objects.equals(aHand, "바위")) {
            if (Objects.equals(bHand, "가위")) {
                System.out.println("A 가 이겼습니다.");
            } else if (Objects.equals(bHand, "바위")) {
                System.out.println("A 와 B 는 비겼습니다.");
            } else if (Objects.equals(bHand, "보")) {
                System.out.println("B 가 이겼습니다.");
            }
        } else if (Objects.equals(aHand, "보")) {
            if (Objects.equals(bHand, "가위")) {
                System.out.println("B 가 이겼습니다.");
            } else if (Objects.equals(bHand, "바위")) {
                System.out.println("A 가 이겼습니다.");
            } else if (Objects.equals(bHand, "보")) {
                System.out.println("A 와 B 는 비겼습니다.");
            }
        }

    }

 

  • 반복문

- for

  • 특정 조건에 따라 반복(끊지 않을 때까지)
  • 무한루프에 주의해야함
[형태]
for (초기값; 조건문; 증가연산) { (연산) }
for ( int i = 0; i < 4; i++ ) { System.out.println( i + " 번째 출력!");}

 

- 향상된 for 문

  • 연속된 변수 목록을 출력할 때 사용
  • 변수 타입과 변수명은 for 문 안에서 연산을 수행 할 변수를 정의
  • 목록변수는 값 여러 개(1,2,3,4,5)를 하나의 변수로 저장하고 싶을 때 사용
[형태]
for (변수 타입 변수 명 : 목록변수)  { (연산) }
int[] numbers = {3,6,9,12,15};
for(int number : numbers) { System.out.print(number + ""); }

 

-while

  • for 문과 마찬가지로 특정 조건에 따라 연산을 반복해서 수행하고 싶을때 사용
  • but! 초기값 없이 조건문만 명시해서 반복
  • 무한루프에 더 주의해야함
[형태]
while(조건문) { (연산) }
while (number < 3) { number++; System.out.println(number + "출력!");}

 

- do while

  • do-while 문으로 사용하면 최초 1회 연산수행 후 조건문을 체크하여 반복 여부 결정
  • 반복하게 된다면 그 이후에는 한번 반복할때마다 조건문을 체크해서 조건문이 false이면 반복을 중단
[형태]
do { (연산) } while(조건문)
int number = 4;
// { } 안에 있는 로직을 먼저 수행
do { System.out.println(number + " 출력");} while (number < 3);

 

- continue 명령 : for 문 또는 while 문에서 해당 순서를 패스하고 싶을 때 continue 명령을 사용

int numer = 0;
        while (numer < 3){
            numer ++;
            if(numer == 2) {
                continue; // 바로 다음 반복분으로 넘어감 -> 2로 다시 시작
            }
            System.out.println(numer + "출력");
        }

 

  • 배열

- 분류통, 자료구조라고도 불림

- 사이즈가 있는 배열은 각 칸마다 순번이 있음!!!!

- 순번은 0부터 시작

- 배열은 생성될때 각 타입별 초기값으로 초기화 되어 채워짐

  • ex) int 는 0, boolean 은 false, String 은 null

- 참조형 변수이기 때문에 실제 값을 담지않고 실제값의 주소값을 저장함

- 초기화

  1. 중괄호{} 를 사용해서 초기화
  2. 반복문 for문을 사용해서 초기화 (향상된 for문도 가능)
  3. Arrays.fill 메소드를 사용해서 초기화 : Arrays 클래스는 Java 에서 기본으로 제공하는 메소드가 담긴 클래스
import java.util.Arrays; // Arrays 클래스

public class Main {

	public static void main(String[] args) {
    
		//1. 배열에 특정값 대입하며 선언
		int[] intArray = {1, 2, 3, 4, 5};
		String[] stringArray = {"a", "b", "c", "d"};

		//2-1. for문을 통해 값을 대입
		for (int i = 0; i < intArray.length; i++) {
			intArray[i] = i;
		}

		//2-2. 향상된 for문을 통한 배열 출력
		for (int i : intArray) {
			System.out.print(i); // 01234
		}

		System.out.println(); // 줄바꿈

		//3. 배열의 주소를 모두 같은값으로 초기화
		Arrays.fill(intArray, 1);//배열의 모든 값을 1로 초기화

		for (int i : intArray) {
			System.out.print(i);  // 11111
		}
	}
}

// 출력
01234
11111

 

- 얕은 복사 : 주소값만 복사되고 실제값은 1개로 유지되는 것

  • 배열 변수간에 대입 연산자(=)를 사용해서 복사를 하게 되면 주소값만 복사됨
  • 하나만 복사 해도 전체에 영향을 줌
int[] a = { 1, 2, 3, 4 };
int[] b = a; // 얕은 복사

b[0] = 3; // b 배열의 0번째 순번값을 3으로 변경

System.out.println(a[0]); // 출력 3  <- a 배열의 0번째 순번값도 3으로 조회됩니다.

 

+ 주소값만 복사

  • 주소값만 복사된다는건 변수명은 서로 다르지만 같은 값을 보고 있다는것
  • ex ) 내가 가진 핸드폰, PC 로 각각 카카오톡에 로그인해도 나의 카톡 계정은 1개인것처럼, 변수명은 여러개지만 결국 실제값은 1개인것과 같음

- 깊은 복사 : 얕은 복사처럼 가짜 복사가 아니라 진짜 새로운 배열을 똑같이 만들고 싶을 때 사용됨

  • 하나씩 꺼내서 복제
int[] a = { 1, 2, 3, 4 };
int[] b = new int[a.length]; 

for (int i = 0; i < a.length; i++) {
    b[i] = a[i]; // 깊은 복사
}

b[0] = 3; // b 배열의 0번째 순번값을 3으로 수정

System.out.println(a[0]); // 출력 1 <- 깊은 복사를 했기 때문에 a 배열은 그대로
  • 여러 메소드를 사용
// 깊은 복사 메서드

        // 1. clone() 메서드
        int[] a = { 1, 2, 3, 4 };
        int[] b = a.clone(); // 가장 간단한 방법입니다.
        // clone() 메서드는 2차원이상 배열에서는 얕은 복사로 동작

        // 2. Arrays.copyOf() 메서드
        int[] a = { 1, 2, 3, 4 };
        int[] b = Arrays.copyOf(a, a.length); // 배열과 함께 length값도 같이 넣어줌

        a[3] = 0;
        System.out.println(a[3]);
        System.out.println(b[3]);

 

- String 배열의 초기화

// 선언 후 하나씩 초기화
String[] stringArray = new String[3];
stringArray[0] = "val1";
stringArray[1] = "val2";
stringArray[2] = "val3";

// 선언과 동시에 초기화.
String[] stringArray1 = new String[]{"val1", "val2", "val3"};
String[] stringArray2 = {"val1", "val2", "val3"};

 

- String 배열 활용

  1. 문자열 = 문자배열
  • char : 문자 배열
  • String :  문자열
  • String = char[] 
기본형 변수와 참조형 변수의 차이
기본형 변수는 소문자로 시작하고 참조형 변수는 대문자로 시작
→ 참조형 변수는 실제값의 주소값을 저장하고 있는 변수
  • String 은 char배열과 같기 때문에 둘 다 문자열을 저장할 수 있는 변수임
  • 하지만 String을 더 많이 쓰는이유는 참조형 변수가 더 많은 기능들을 가지고 있음
  • char배열에는 없은 String 만 가지고 있는 기능
length() int 문자열의 길이를 반환한다.
charAt(int index) char 문자열에서 해당 index의 문자를 반환한다.
substring(int from, int to) String 문자열에서 해당 범위(from~to)에 있는 문자열을 반환한다. (to는 범위에 포함되지 않음)
equals(String str) boolean 문자열의 내용이 같은지 확인한다. 같으면 결과는 true, 다르면 false가 된다.
toCharArray() char[] 문자열을 문자배열(char[])로 변환해서 반환한다.
new String(char[] charArr) String 문자배열(char[]) 을 받아서 String으로 복사해서 반환한다.

 

다차원 배열

- 초기화

  1. 중괄호를 사용해 선언과 동시에 초기화
// 중괄호를 사용해 초기화

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

   2. 선언/생성 이후 반복문을 통해 초기화

// 반복문을 통한 초기화

int[][] array = new int[2][3]; // 최초 선언

for (int i = 0; i < array.length; i++) {
    for (int j = 0; j < array[i].length; j++) {
        arr[i][j] = 0;  // i, j 인덱스 라고 부름
    }
}

 

- 다차원 배열의 조회

  • 2차원 배열 조회할때는 2차원 인덱스를 가진만큼 2중 반복문을 통해 출력할 수 있음
    • 이중 반복문을 통해 가변 배열도 출력 가능함
// 가변 2차원 배열 조회
int[][] array = {
	{10, 20, 30},
	{10, 20, 30, 40},
	{10, 20}
};

for (int i = 0; i < array.length; i++) { // 1차원 길이
	for (int j = 0; j < array[i].length; j++) { // 2차원 길이
		System.out.println(array[i][j]); // 2중 반복문으로 i, j 인덱스 순회
	}
}

// 출력
10
20
30
10
20
30
40
10
20

 

* 단건조회(ary[2]) / 다건조회(for 문 / 향상된 for 문)

 

  • 컬렉션

: 배열의 한계를 이겨낼 수 있는 더 많은 기능을 제공하는 자료구조를 제공함

- 기능 : 크기 자동조정/ 추가/ 수정/ 삭제/ 반복/ 순회/ 필터/ 포함확인 등

- 참조형 변수만 사용

<자주쓰는 참조형 변수>
int 의 참조형 변수 = Integer
long 의 참조형 변수 = Long
double 의 참조형 변수 = Double
String 은 원래 참조형 변수 

 

- 컬렉션의 종류

  • List, Set , Queue , Map
  • List : 순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷
  • Queue : 빨대처럼 한쪽에서 데이터를 넣고 반대쪽에서 데이터를 뺄 수 있는 집합
    • First In First Out : 먼저들어간 순서대로 값을 조회할 수 있음
  • Set : 순서가 없는 데이터의 집합 (데이터 중복 허용 안함) - 순서없고 중복없는 배열
  • Map : 순서가 없는 (Key,Value) 쌍으로 이루어진 데이터의 집합 (Key값 중복 허용 안함 = unique)

1. List

 - 순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷

 

1-1. ArrayList

- 배열(Array)처럼 일렬로 데이터를 저장하고 조회하여 순번값(인덱스)로 값을 하나씩 조회할 수 있음

  • 특징 : 배열처럼 크기가 정해져 있지않고 필요할 때마다 크기가 점점 더 늘어남
    • Array처럼 크기를 고정하여 생성하는 것을 정적배열, ArrayList처럼 크기가 가변적으로 늘어나는 것을 동적 배열이라고 함
      • Array는 메모리에 연속된 공간을 요청한 사이즈 만큼 받아서 실제값을 저장하는 기본형 변수로 저장하기 때문에 정적배열 
      • ArrayList 는 생성시점에 작은 연속된 공간을 요청해서 참조형 변수들을 담아놓고, 값이 추가될때 더 큰 공간이 필요하면 더큰 공간을 받아서 저장하기 때문에 동적배열
      ▶ 기본형 변수로 저장하는 Array 는 정적배열이고, 참조형 변수로 저장하는 ArrayList 는 동적배열

- 기능

  • 선언 : ArrayList<Integer> intList
  • 생성 : new ArrayList<Integer>();
  • 초기화 : 사이즈를 지정하는것이 없기 때문에 초기화가 필요 없음
  • 값 추가 : intList.add({추가할 값})
  • 값 수정 : intList.set({수정할 순번}, {수정할 값})
  • 값 삭제 : intList.remove({삭제할 순번})
  • 전체 출력 : intList.toString() 전체 값을 대괄호[]로 묶어서 출력
  • 전체 제거 : intList.clear()

1-2. LinkedList

- 메모리에 남는 공간을 요청해서 여기저기 나누어서 실제값을 담아놓고, 실제값이 있는 주소값으로 목록을 구성하고 저장

- 특징

  • 기본적인 기능은 ArrayList 와 동일하지만 LinkedList 는 값을 나누어 담기 때문에 모든값을 조회하는 속도가 느림. 대신 값을 중간에 추가하거나 삭제할때는 속도가 빠름
  • 중간에 값을 추가하는 기능이 있습니다. (속도 빠름)

- 기능

  • 선언 : LinkedList<Integer> linkedList
  • 생성 : new LinkedList<Integer>();
  • 초기화 : 사이즈를 지정하는 것이 없음 -> 초기화가 필요X
  • 값 추가 : linkedList.add({추가할 값})
  • 값 중간에 추가 : linkedList.add({추가할 순번}, {추가할 값})
  • 값 수정 : linkedList.set({수정할 순번}, {수정할 값})
  • 값 삭제 : linkedList.remove({삭제할 순번})
  • 전체 출력 : linkedList.toString() -> 전체 값을 대괄호[]로 묶어서 출력
  • 전체 제거 : linkedList.clear()

1-3. Stack

- 값을 수직으로 쌓아놓고 넣었다가 빼서 조회하는 형식으로 데이터를 관리함 (FIFO)

 

- 특징

  • 밑에서 위로 쌓고, 꺼낼때는 위에서 부터 꺼내는 형식.
  • 넣기(push()), 조회(peek()), 꺼내기(pop()) 기능만 있음
  • 최근 저장된 데이터를 나열하고 싶거나 데이터의 중복처리를 막고싶을때 사용함(불편함을 감수하고도)

- 기능

  • 선언 : Stack<Integer> intStack
  • 생성 : new Stack<Integer>();
  • 추가 : intStack.push({추가할 값})
  • 조회 : intStack.peek() 맨 위값을 조회
  • 꺼내기 : intStack.pop() 맨 위값을 꺼냄 (꺼내고나면 삭제됨)

 

 

continue 문이 처음에 헷갈렸다. continue가 나오면 바로 다음 반복문으로 넘어간다고 설명을 해주셨는데 2로 다시 시작을 한다고? 생각을 했었다. 근데 다시 생각해보니까 0 -> 1 -> 2 이런식으로 값이 입력되니까 2로 넘어가는게 맞았다 ㅠㅠ 바보같이 헤매고 있었다..