Java/whiteship-java-study

3주차 - 자바 연산자

ysk(0soo) 2022. 7. 31. 19:14

백기선 님의 유튜브 온라인 자바 스터디를 정리한 글입니다

3주차 - 연산자

목표

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

학습할 것

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

연산

연산 (operations) : 프로그램에서 데이터를 처리하여 결과를 산출하는 것
연산자 (operator) : 연산에 사용되는 표시나 기호
피연산자 (operand) : 연산의 대상이 되는 데이터
연산식 (expressions) : 연산자와 피연산자로 연산의 과정을 기술한 것

출처: https://xxxelppa.tistory.com/196?category=858435 [한칸짜리책상서랍:티스토리]

산술 연산자

연산 연산자 수식 결과
덧셈 A+B A와 B를 더한 값
뺄셈 A-B A에서 B를 뺀 값
곱셈 × A×B A와 B를 곱한 값
나눗셈 / A/B A÷B의 몫
나머지 A%B A÷B의 나머지
  • 사칙 연산에 사용되는 연산자 입니다.
  • 산술 연산자는 모두 두 개의 피연산자를 가지는 이항 연산자이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽입니다.

연산자의 우선순위(operator precedence)와 결합 방향(associativity)

연산자의 우선순위는 수식 내에 여러 연산자가 함께 등장할 때, 어느 연산자가 먼저 처리될 것인가를 결정합니다.

우선순위 연산자 설명 결합 방향
1 [] 첨자 연산자 왼쪽에서 오른쪽으로
. 멤버 연산자 왼쪽에서 오른쪽으로
2 ++ 후위 증가 연산자 왼쪽에서 오른쪽으로
-- 후위 감소 연산자 왼쪽에서 오른쪽으로
3 ! 논리 NOT 연산자 오른쪽에서 왼쪽으로
~ 비트 NOT 연산자 오른쪽에서 왼쪽으로
+ 양의 부호 (단항 연산자) 오른쪽에서 왼쪽으로
- 음의 부호 (단항 연산자) 오른쪽에서 왼쪽으로
++ 전위 증가 연산자 오른쪽에서 왼쪽으로
-- 전위 감소 연산자 오른쪽에서 왼쪽으로
(타입) 타입 캐스트 연산자 오른쪽에서 왼쪽으로
4 * 곱셈 연산자 왼쪽에서 오른쪽으로
/ 나눗셈 연산자 왼쪽에서 오른쪽으로
% 나머지 연산자 왼쪽에서 오른쪽으로
5 + 덧셈 연산자 (이항 연산자) 왼쪽에서 오른쪽으로
- 뺄셈 연산자 (이항 연산자) 왼쪽에서 오른쪽으로
6 << 비트 왼쪽 시프트 연산자 왼쪽에서 오른쪽으로
>> 부호 비트를 확장하면서 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
>>> 부호 비트까지 모두 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
7 < 관계 연산자(보다 작은) 왼쪽에서 오른쪽으로
<= 관계 연산자(보다 작거나 같은) 왼쪽에서 오른쪽으로
> 관계 연산자(보다 큰) 왼쪽에서 오른쪽으로
>= 관계 연산자(보다 크거나 같은) 왼쪽에서 오른쪽으로
instanceof 인스턴스의 실제 타입 반환 왼쪽에서 오른쪽으로
8 == 관계 연산자(와 같은) 왼쪽에서 오른쪽으로
!= 관계 연산자(와 같지 않은) 왼쪽에서 오른쪽으로
9 & 비트 AND 연산자 왼쪽에서 오른쪽으로
10 ^ 비트 XOR 연산자 왼쪽에서 오른쪽으로
11 | 비트 OR 연산자 왼쪽에서 오른쪽으로
12 && 논리 AND 연산자 왼쪽에서 오른쪽으로
13 || 논리 OR 연산자 왼쪽에서 오른쪽으로
14 ? : 삼항 조건 연산자 오른쪽에서 왼쪽으로
15 = 대입 연산자 및 복합 대입 연산자
(=, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, ^=, |=)
오른쪽에서 왼쪽으로

비트 연산자

  • 비트 연산자는 논리 연산자와 비슷하지만 비트(bit) 단위로 논리 연산을 할 때 사용하는 연산자 입니다.

  • 비트 연산은 1과 0을 가지고 이루어집니다.

비트 연산자 설명
& 대응되는 비트가 모두 1이면 1을 반환함. (비트 AND 연산)
| 대응되는 비트 중에서 하나라도 1이면 1을 반환함. (비트 OR 연산)
^ 대응되는 비트가 서로 다르면 1을 반환함. (비트 XOR 연산)
~ 비트를 1이면 0으로, 0이면 1로 반전시킴. (비트 NOT 연산, 1의 보수)
<< 명시된 수만큼 비트들을 전부 왼쪽으로 이동시킴. (left shift 연산)
>> 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴. (right shift 연산)
>>> 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 됨.
  • NOT ( ~ ) 연산자는 하나의 피연산자 비트를 비트 또는 논리 반전하는 단항 연산자입니다.
  • AND ( & ) 연산자는 두 개의 피연산자의 비트 또는 논리 and를 수행하는 이항 연산자입니다.
  • OR ( | ) 연산자는 2 개의 피연산자의 비트 또는 논리 또는을 수행하는2 진 연산자입니다.
  • XOR ( ^ ) 연산자는 두 개의 피연산자의 비트 또는 논리 "배타적 논리합"을 수행하는 이항 연산자입니다.

관계 연산자

  • 관계 연산자 (Relational Operator) : 비교 연산자라고도 부릅니다.

  • 피연산자 사이의 상대적인 크기를 비교하는 연산자입니다.

    • 왼쪽의 피연산자와 오른쪽의 피연산자를 비교하여 어느 쪽이 더 큰지, 작은지, 또는 서로 같은지를 비교, 판단합니다.
  • 결합 방향은 왼쪽에서 오른쪽입니다.

비교 연산자 설명 이름
== 왼쪽과 오른쪽의 피연산자가 같으면 참을 반환함. eq (equal)
!= 왼쪽과 오른쪽의 피연산자가 같지 않으면 참을 반환함. ne (not eqaul)
> 왼쪽이 오른쪽의 피연산자보다 크면 참을 반환함. gt (greater)
>= 왼쪽이 오른쪽의 피연산자보다 크거나 같으면 참을 반환함. ge ( greater or eqaul)
< 왼쪽이 오른쪽의 피연산자보다 작으면 참을 반환함. lt (little)
<= 왼쪽이 오른쪽의 피연산자보다 작거나 같으면 참을 반환함. le (little or equal)

논리 연산자

  • 비트 연산과 비슷하지만, 주어진 논리식을 판단하여 참(true)와 거짓(false)를 결정하는 연산자 입니다.
  • AND(&&), OR(||) 연산은 두 피연산자를 연산하여 결과를 반환합니다.
  • NOT(!) 연산은 단항 연산자이며, 결과를 반환합니다.
논리 연산자 설명
&& 논리식이 모두 참이면 참을 반환함. (논리 AND 연산)
|| 논리식 중에서 하나라도 참이면 참을 반환함. (논리 OR 연산)
! 논리식의 결과가 참이면 거짓을, 거짓이면 참을 반환함. (논리 NOT 연산)

instanceof

  • 객체가 특정 클래스 / 인터페이스 유형인지 여부를 확인합니다.

    • 해당 객체가 어떤 클래스나 인터페이스로부터 생성되었는지를 판별해 주는 역할을 합니다.
  • 객체 타입을 확인하는데 사용하는 연산자. 해당 여부를 true, false 로 알려준다. 부모 객체의 인스턴스인지 자식 객체인지 를 알려줄 때 사용합니다.

  • (레퍼런스 타입 변수) instanceof (레퍼런스 데이터 타입)

    • 레퍼런스 타입 변수가 레퍼런스 데이터 타입인지 확인해보는 연산
    • 클래스도 사용자 정의 자료형이며 레퍼런스 데이터타입입니다.

assignment(=) operator

  • 대입 또는 할당 연산자라고 부릅니다.
  • 변수에 값을 대입할 떄 사용하는 이항 연산자 입니다.
대입 연산자 설명
= 왼쪽의 피연산자에 오른쪽의 피연산자를 대입함.
+= 왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
-= 왼쪽의 피연산자에서 오른쪽의 피연산자를 뺀 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
*= 왼쪽의 피연산자에 오른쪽의 피연산자를 곱한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
/= 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
%= 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 나머지를 왼쪽의 피연산자에 대입함.
&= 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 AND 연산한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
|= 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 OR 연산한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
^= 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 XOR 연산한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
<<= 왼쪽의 피연산자를 오른쪽의 피연산자만큼 왼쪽 시프트한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
>>= 왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호를 유지하며 오른쪽 시프트한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.
>>>= 왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호에 상관없이 오른쪽 시프트한 후, 그 결괏값을 왼쪽의 피연산자에 대입함.

화살표(->) 연산자

  • 자바 8이후부터 람다가 도입 되면서 등장한 연산자입니다.

  • 람다 표현식에 사용합니다.

    • 람다 표현식(lambda expression)이란 간단히 말해 메소드를 하나의 식으로 표현한 것입니다.
    • 람다 표현식은 익명 함수, 또는 함수형 인터페이스를 구현하는 익명 클래스의 인스턴스를 보다 정확하게 정의합니다.
  • 문법

    • (매개변수목록) -> { 함수 }

    • a -> a + 1;
      a -> {return a + 10;}
  • 자바에서 람다 표현식을 작성할 때 유의해야 할 사항은 다음과 같습니다.

    1. 매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있습니다.

    2. 매개변수가 하나인 경우에는 괄호(())를 생략할 수 있습니다.

      1. 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있습니다. (이때 세미콜론(;)은 붙이지 않음)
    3. 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호({})를 생략할 수 없습니다.

    4. return 문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 됩니다. (이때 세미콜론(;)은 붙이지 않음)

3항 연산자

  • 삼항 연산자는 자바에서 유일하게 피연산자를 세 개나 가지는 조건 연산자입니다.

  • 너무 길면 활용하지 않는 편이 가독성에 좋습니다

  • 문법 : 조건식 ? 반환값 1 : 반환값 2

    • 조건식이 true이면 반환값 1을 반환하고, false 이면 반환값 2를 반환합니다.
  • 3항 연산 안에 또 다른 3항 연산을 중첩해서 사용할 수 있습니다.

    • 조건식1 ? 조건식2 : 조건식3

연산자 우선 순위

  • 수학에서와 연산이 같습니다.
우선 순위 연산자 내용
1 (),[] 괄호 / 대괄호
2 !,~,++,-- 부정/ 증감 연산자
3 *, /, % 곳셈/나눗셈 연산
4 +, - 덧셈/빼기 연산
5 <<,>>,>>> 비트단위 쉬프트 연산자
6 <.<=,>,>= 관계 연산자
8 ==, !=
9 & 비트단위의 논리연산
10 ^ XOR. 배타적 OR
11 && 논리곱
12 || 논리합
13 ?: 조건부 연산자
14 =,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,~= 대입 할당 연산자
  • '>>>'는 자바에만 있는 연산자로 부호에 상관없이 비트 값들을 주어진 비트 수 만큼 오른쪽으로 이동시킨 후 빈 공간을 모두 0으로 채운다.

    • unsigned로 연산하는것이다.

    • int mid = (start + end) / 2; 일 때 오버 플로우가 날 수 있다.

      • start 나 end 연산의 결괏값이 21억을 넘을 때. 정수형은 21억까지니까.

      • unsigned로 처리하면 연산할 수 있다.

    • int mid = (start + end) >>> 1;

      • 개간지 계산법.. unsigned로 연산해버려서 21억 오버플로우를 방지할 수 있다.

(optional) Java 13. switch 연산자

  • 자바 12에서는 옵션은 주고 사용해야 하고 자바 13부터 사용이 가능한 오퍼레이터입니다.

    • operator가 추가 된것입니다.
  • [switch statement]

    • 다수의 case,break가 존재하게 된다.
    • break; 를 빼먹을 경우 다음 분기로 넘어가게 됨.
    • return값이 존재할수없다.
  • [switch operator]

    • break를 사용하지 않아도 된다.

    • yield 존재함

    • return값 존재해도됨

    • case -> A 같은 형식으로 표현가능

    • switch의 반환값이 따로 필요하지 않거나 case가 switch 들어오는 모든 인자를 커버하는 경우

    • default 항목을 넣어주지 않아도 되나 그렇지 않은 경우는 default -> code를 작성해야 한다.

[Java12]

  1. ->(화살표) 표현이 가능하고 data만 존재할 경우 return이 가능하다.

  2. -> 구문을 사용할 경우 break;를 적지 않아도 다음 case 구문으로 넘어가지 않는다.

  3. -> 표현 오른쪽은 꼭 단일 수행일 필요는 없다. 블록 {} 안에서의 작업도 가능하다.

[Java13]

  1. yield 예약어가 추가됨. yield x 하게 되면 x가 리턴됨.

  2. yield는 예약어이지만 변수명으로 사용가능하다. int yield = 3;

  • 자바 13버전 이전의 switch case 문법
// 13 이전
public void printMyState(String day) {
  switch (day) {
    case "MONDAY":
    case "TUESDAY":
    case "WEDNSESDAY":
    case "THURSDAY":
    case "FRIDAY":
      System.out.println("일하는날은 피곤해서 상태가 좋지 않네..");
      break;
    case "SATURDAY":
    case "SUNDAY":
      System.out.println("쉬는날이라 기분이 좋아졌어!");
      break;
  }
}

// 13버전
public String getMyStateStr(String day) {
  switch (day) {
    case "MONDAY":
    case "TUESDAY":
    case "WEDNSESDAY":
    case "THURSDAY":
    case "FRIDAY":
      return "일하는날은 피곤해서 상태가 좋지 않네..";
    case "SATURDAY":
    case "SUNDAY":
      return"쉬는날이라 기분이 좋아졌어!";
  }
}

public static void main(String[] args) {
  System.out.println(getMyStateStr("MONDAY")); // -> 일하는날은 피곤해서 상태가 좋지 않네..
}

참조 및 출처

http://www.tcpschool.com/java/

https://catch-me-java.tistory.com/31