자바 기본 복습 3. 연산자

장난·2021년 5월 9일
0

자바 기본

목록 보기
3/15
post-thumbnail

3주차 과제: 연산자


📜 시작에 앞서

  • 백기선 님의 라이브 스터디(2020년 11월부터 2021년 3월까지) 커리큘럼을 따라 진행한 학습입니다
  • 뒤늦게 알게 되어 스터디 참여는 못했지만 남아있는 스터디 깃허브 주소유튜브 영상을 참고했습니다

📌 목표

자바가 제공하는 다양한 연산자를 학습하세요.


📌 학습할 것

  • 산술 연산자
  • 비트 연산자
  • 관계 연산자
  • 논리 연산자
  • instanceof
  • assignment(=) operator
  • 화살표(->) 연산자
  • 3항 연산자
  • 연산자 우선 순위
  • (optional) Java 13. switch 연산자

📑 ​산술 연산자

  • boolean을 제외한 기본형에서 사용 가능
  • 두 피연산자의 타입을 보다 큰 타입으로 자동 형변환
    • 피연산자의 타입이 int보다 작은 타입이면 int로 변환
  • int는 소수점 이하를 버리니 결과값 변화에 주의
  • + 더하기
  • - 빼기
  • * 곱하기
  • / 나누기 몫
    • 정수를 0으로 나눌 시 ArithmeticException 에러
    • 부동 소수점 형식에서 0으로 나눌 시 몫은 Infinity
  • % 나누기 나머지
    • 부동 소수점 형식에서 0으로 나눌 시 나머지는 NaN

산술 연산자 이용 반올림

public static void main(String[] args) {

    double pi = 3.141592;

    double shortPi1 = (int) (pi * 100 + 0.5) / 100.0;
    double shortPi2 = Math.round(pi * 100) / 100.0;
    
    System.out.println(shortPi1);	//3.14
    System.out.println(shortPi2);	//3.14
}

📑 ​비트 연산자

  • 비트 값을 기반으로 하는 연산자
    • 부동소수점, 부울, 객체, 배열을 피연산자로 사용할 수 없다
비트 연산자결과
&AND. 두 비트가 모두 1일 때만 결과 값 1
|OR. 두 비트 중 하나만 1이어도 결과 값 1
^XOR. 두 비트가 같은 값이면 결과 값 1
~비트 반전
x << nx의 각 비트가 왼쪽으로 n비트 이동. 빈자리는 0. (기존 값에 2n만큼 곱하는 것)
x >> nx의 각 비트가 오른쪽으로 n비트 이동. 빈자리는 부호비트 유지 (기존 값에 2n만큼 나누는 것)
x >>> nx의 각 비트가 오른쪽으로 n비트 이동. 빈자리는 0.

중간 값 구하기: 백기선 님 스터디 영상 中

int start = 2_000_000_000;
int end = 2_100_000_000;
int mid = (start + end)/2;
//위처럼 중간 값을 구하는 방식은 괄호 안 계산에서 오버플로우가 날 수 있기 때문에 안전하지 않다.

//쉬운 해결법
int mid = start + (end - start) / 2;

//멋 한번 내고 싶을 때
int mid = (start + end) >>> 1;

비트 연산자 잘 안 쓰니까 심심할까봐

문제풀이: 백기선 님 스터디 영상 中

int형 배열이 있다.

해당 배열에 들어있는 숫자들은 오직 한 숫자를 제외하고는 모두 두 번씩 들어있다.

오직 한 번만 등장하는 숫자를 찾는 코드를 작성하라.

여러 방법이 있겠지만 비트연산자 사용 모습

public class Hello{
    
    public static void main(String[] args){
        Hello hello = new Hello();
        int result = hello.solution(new int[] {5,5,4,4,3,3,2,2,1});
        System.out.println(result);
    }
    
    // TODO XOR
    // 비트가 서로 다르면 1, 같으면 0
    /*
    	5 ^ 0 = 5
    	5 ^ 5 = 0
    	비트
    	101 101
    	000 101
    	--- ---
    	101 000
    	5 ^ 1 ^ 5 => (5 ^ 5) ^ 1 = 0 ^ 1 = 1
    */
    private int solution(int[] numbers){
        int result = 0;
        for(int number : numbers){
            reslut ^= number;
        }
        return result;
    }
}

📑 ​관계 연산자

  • 두 피연산자를 비교
  • 결과는 ture false 중 하나
  • 비교하는 피연산자 타입이 다르면 자료형의 범위가 큰 쪽으로 자동 형변환 후 비교
    • 서로 형변환 불가능하다면 비교 불가
관계 연산자결과
>좌변 값이 크면 true, 아니면 false
<좌변 값이 작으면 true, 아니면 false
>=좌변 값이 크거나 같으면 true, 아니면 false
<=좌변 값이 작거나 같으면 true, 아니면 false
==두 값이 같으면 true, 아니면 false
!=두 값이 다르면 true, 아미녀 false
  • 등가비교 연산자 == !=참조형의 경우 객체의 주소값을 비교

📑 ​논리 연산자

  • 두 피연산자에 대한 논리 연산 수행
  • 피연산자는 boolean만 허용
논리 연산자결과
&&두 피연산자가 모두 true일때만 결과값 true
||두 피연산자 중 하나라도 true라면 결과값 ture
!truefalse, falsetrue 리턴
  • 단락 회로 평가(Short Circuit Evaluation: SCE)
    • &&, || 연산 중 두 항을 모두 시행하지 않더라도 결과 값을 알 수 있을 때, 나머지 항을 실행하지 않는다
    • 비트 연산자 &, | 의 두 피연산자가 boolean 인 경우 논리 연산자 처럼 사용될 수 있는데, 이떄는 단락 회로 평가가 일어나지 않는다

📑 ​instanceof

  • 좌변이 우변의 피연산자 타입인지 평가
  • truefalse 리턴
  • null 평가 시 항상 false 리턴

캐스트 연산자와 함께 사용되는 모습

Animal cat = new Cat();
if(cat instanceof Cat){			//cat의 인스턴스 자료형이 Cat이라면
    Cat cat = (Cat) cat;
}

📑 ​assignment(=) operator

  • 우변(rvalue)을 좌변(lvalue)에 저장
  • 진행방향이 오른쪽에서 왼쪽
  • lvalue는 변수처럼 값을 변경할 수 있는 것이어야 하고 rvalue는 거기에 맞는 타입이 와야 한다

복합 대입 연산자

op==
i += 1;i = i + 1;
i -= 1;i = i - 1;
i *= 1;i = i * 1;
i /= 1;i = i / 1;
i %= 1;i = i % 1;
i <<= 1;i = i << 1;
i >>= 1;i = i >> 1;
i &= 1;i = i & 1;
i ^= 1;i = i ^ 1;
i |= 1;i = i | 1;
i *= 10 + j;i = i * (10 + j);

출저: 자바의 정석


📑 화살표(->) 연산자

  • 람다 표현식에서 사용하는 연산자로, 파라미터와 바디 사이에 표시
  • (Parameters) -> { Body }
    • 함수 바디가 한 줄이라면 {} 생략 가능
    • 아규먼트가 하나라면 () 생략 가능
Thread thread = new Thread( () -> {
    System.out.println("람다 표현식 사용")
});

람다 표현식?


📑 ​3항 연산자

  • 현재까지 3 개의 피연산자를 필요로 하는 삼항 연산자는 조건 연산자뿐
  • 조건식 ? 식1 : 식2
  • 조건식이 true식1, false식2를 리턴
//삼항 연산자
void fun1() {
    return Condition1 ? value1
        : Condition2 ? value2
        : value3
}

//if문
void fun2() {
    if (condition1) {
        return value1;
    } else if (condition2) {
        return value2;
    } else {
        return value3
    }
}

📑 ​연산자 우선 순위

  • 단항 이항 삼항 연산자 순으로 우선순위가 높다
  • 산술 관계 논리 대입 연산자 순으로 우선순위가 높고, () 사용으로 조절 가능
  • 단항 연산자와 대입연산자의 진행 방향은 오른쪽에서 왼쪽. 나머지는 왼쪽에서 오른쪽

연산자 우선순위 표

PrecedenceOperatorTypeAssociativity
15() [] ·Parentheses Array subscript Member selectionLeft to Right
14++ --Unary post-increment Unary post-decrementRight to left
13++ -- + - ! ~ ( type )Unary pre-increment Unary pre-decrement Unary plus Unary minus Unary logical negation Unary bitwise complement Unary type castRight to left
12* / %Multiplication Division ModulusLeft to right
11+ -Addition SubtractionLeft to right
10<< >> >>>Bitwise left shift Bitwise right shift with sign extension Bitwise right shift with zero extensionLeft to right
9< <= > >= instanceofRelational less than Relational less than or equal Relational greater than Relational greater than or equal Type comparison (objects only)Left to right
8== !=Relational is equal to Relational is not equal toLeft to right
7&Bitwise ANDLeft to right
6^Bitwise exclusive ORLeft to right
5|Bitwise inclusive ORLeft to right
4&&Logical ANDLeft to right
3||Logical ORLeft to right
2? :Ternary conditionalRight to left
1= += -= *= /= %=Assignment Addition assignment Subtraction assignment Multiplication assignment Division assignment Modulus assignmentRight to left

Larger number means higher precedence.

출저: bilkent: Java Operator Precedence Table


📑 Java 13. switch 연산자


기존 스위치문 (switch statement)

switch (day) {
    case MONDAY:
    case TUESDAY:
        System.out.println("A 하는 날");
        break;
    case WEDNESDAY:
    case THURSDAY:
    case FRIDAY:
        System.out.println("B 하는 날");
        break;
    case SATURDAY:
        System.out.println("C 하는 날");
        break;
	case SUNDAY:
        System.out.println("쉬는 날");
        break;
}
  • 코드가 길어지며 가시성이 떨어진다
    • 실수하기 쉽다

java 12 스위치문(switch statement)과 표현식(switch expression)

//스위치문
String toDo;
switch (day) {
    case MONDAY, TUESDAY		-> toDo = "A";
    case WEDNESDAY, THURSDAY, FRIDAY	-> toDo = "B";
    case SATURDAY			-> toDo = "C";
    case SUNDAY				-> toDo = "D";
}

//스위치 표현식
String toDo = switch (day) {
    case MONDAY, TUESDAY		-> "A";
    case WEDNESDAY, THURSDAY, FRIDAY	-> "B";
    case SATURDAY			-> "C";
    case SUNDAY				-> "D";
};

int result = switch (num) {
    case "one":
        break 1;
    case "two":
        break 2;
};
  • case에 여러 값 설정 가능
  • 새로운 표현식 case L -> 사용 가능
    • case L -> 오른쪽에 있는 코드만 실행되며 break 생략
  • 스위치 표현식 사용해 더 가시성 좋은 코드 작성 가능
    • 가능한 모든 값에 대해 일치하는 스위치 레이블이 있어야 한다 (일반적으로 default 필요)
    • break <value> 사용 가능

java 13 스위치 표현식

int result = switch (num) {
	case "one":	yield 1;
	case "two":	yield 2;
	default:	yield 0;};
  • 스위치 표현식에서 break <value>yield <value>로 변경

참고: openjdk: JEP 354: Switch Expressions (Second Preview)

0개의 댓글