목표
학습할 것
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
산술 연산자
- 사칙연산을 다루는 연산자
- 가장 기본적이며 가장 많이 사용되는 연산자
- 두 개의 피연산자를 가지는 이항 연산자이며 피연산자들의 결합 방향은 왼쪽에서 오른쪽임
연산자 |
설명 |
+ |
왼쪽의 피연산자에 오른쪽의 피연산자를 더함 |
- |
왼쪽의 피연산자에서 오른쪽의 피연산자를 뺌 |
* |
왼쪽의 피연산자에 오른쪽의 피연산자를 곱함 |
/ |
왼쪽의 피연산자를 오른쪽의 피연산자로 나눔 |
% |
왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후 그 나머지를 반환 |
int x = 10;
int y = 5;
System.out.println(x + y);// 15
System.out.println(x - y);// 5
System.out.println(x * y);// 50
System.out.println(x / y);// 2
System.out.println(x % y);// 0
System.out.println(y + x);// 15
System.out.println(y - x);// -5
System.out.println(y * x);// 50
System.out.println(y / x);// 0
System.out.println(y % x);// 5
- 나누기와 곱하기 연산 방식은 비트를 shift하며 계산을 하기 때문에 몫과 나머지를 구하는데 최적화 되어있음
비트 연산자
- 논리 연산자와 비슷하지만, 비트 단위로 논리 연산을 할 때 사용함
- 비트 단위로 왼쪽이나 오른쪽으로 전체 비트를 이동하거나 1의 보수를 만들 때 사용함
연산자 |
설명 |
& |
대응되는 비트가 모두 1이면 1을 반환(비트 AND 연산) |
| |
대응되는 비트 중에서 하나라도 1이면 1을 반환(비트 OR 연산) |
^ |
대응되는 비트가 서로 다르면 1을 반환(비트 XOR 연산) |
~ |
비트를 1이면 0으로, 0이면 1로 반전시킴(비트 NOT 연산, 1의 보수) |
<< |
명시된 수만큼 비트들을 전부 왼쪽으로 이동(left shift 연산) |
>> |
부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동(right shift 연산) |
>>> |
지정한 수만큼 비트를 전부 오른쪽으로 이동, 새로운 비트는 전부 0 |
int x = 8;
int y = 2;
System.out.println(x & y);// 0
System.out.println(x | y);// 10
System.out.println(x ^ y);// 10
System.out.println(~x);// -9
System.out.println(x << y);// 32
System.out.println(x >> y);// 2
System.out.println(x >>> y);// 2
int start = 2100000000;
int end = 2100000000;
int mid = (start + end) / 2; // 오버플로우가 날 수 있는 코드
System.out.println(mid); // -47483648 -> 이상한 숫자가 나옴
int mid2 = start + (end - start) / 2; // 안전한 코드
System.out.println(mid2); // 2100000000
int mid3 = (start + end) >>> 1; // 안전한 코드(비트 연산자 이용), 양수에서만 가능
System.out.println(mid3); // 2100000000
public class OperatorTest {
// TODO numbers라는 int형 배열이 있다.
// 해당 배열에 들어있는 숫자들은 오직 한 숫자를 제외하고는 모두 두번씩 들어있다.
// 오직 한 번만 등장하는 숫자를 찾는 코드를 작성하라.
public static void main(String[] args) {
Solution solution = new Solution();
int result = solution.calculate(new int[] {5,2,4,10,2,4,5});
System.out.println(result);
}
//TODO XOR 연산 사용
private static class Solution {
int calculate(int[] numbers){
int result = 0;
for (int number : numbers) {
result ^= number;
}
return result;
}
}
}
관계 연산자
- 비교 연산자라고도 부름
- 피연산자 사이의 상대적인 크기를 판단하는 연산자
- 왼쪽의 피연산자와 오른쪽의 피연산자를 비교하여 어느 쪽이 더 큰지, 작은지, 또는 서로 같은지를 판단함
- 모두 두개의 피연산자를 가지는 이항 연산자이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽임
연산자 |
설명 |
== |
왼쪽의 피연산자와 오른쪽의 피연산자가 같으면 참을 반환 |
!= |
왼쪽의 피연산자와 오른쪽의 피연산자가 같지 않으면 참을 반환 |
> |
왼쪽의 피연산자가 오른쪽의 피연산자보다 크면 참을 반환 |
>= |
왼쪽의 피연산자가 오른쪽의 피연산자보다 크거나 같으면 참을 반환 |
< |
왼쪽의 피연산자가 오른쪽의 피연산자보다 작으면 참을 반환 |
<= |
왼쪽의 피연산자가 오른쪽의 피연산자보다 작거나 같으면 참을 반환 |
int x = 8;
int y = 2;
System.out.println(x == y);// false
System.out.println(x != y);// true
System.out.println(x > y);// true
System.out.println(x >= y);// true
System.out.println(x < y);// false
System.out.println(x <= y);// false
논리 연산자
- 주어진 논리식을 판단하여 true와 false을 결정함
- AND 연산과 OR 연산은 두개의 피연산자를 가지는 이항 연산자이며 피연산자들의 결합 방향은 왼쪽에서 오른쪽임
- NOT 연산자는 피연산자가 단 하나뿐인 단항 연산자이며 피연산자의 결합 방향은 오른쪽에서 왼쪽임
연산자 |
설명 |
&, && |
논리식이 모두 참이면 참을 반환(논리 AND 연산) |
|, || |
논리식 중에서 하나라도 참이면 참을 반환(논리 OR 연산) |
! |
논리식의 결과가 참이면 거짓을, 거짓이면 참을 반환(논리 NOT 연산) |
A |
B |
A & B |
A | B |
!A |
true |
true |
true |
true |
false |
true |
false |
false |
true |
false |
false |
true |
false |
true |
true |
false |
false |
false |
false |
true |
int x = 0;
int y = 0;
if(x++ == 0 || y++ == 0){
System.out.println("plus");
}
System.out.println(x); // x = 1
System.out.println(y); // y = 0
int x = 0;
int y = 0;
if(x++ == 0 | y++ == 0){
System.out.println("plus");
}
System.out.println(x); // x = 1
System.out.println(y); // y = 1
// ||, && 과 |, & 의 차이는 ||은 첫번째 조건식 검사후 이게 맞으면
// 두번째 조건식은 건너뛰어 불필요한 연산을 줄이고 효율적으로 실행시키지만
// |는 모든 조건식을 전부 실행시킴
instanceof
- 참조 변수가 참조하고 있는 인스턴스의 실제 타입을 반환
- 해당 객체가 어떤 클래스나 인터페이스로부터 생성되었는지를 판별해 주는 역할
Integer x = 8;
System.out.println(x instanceof Object);// true
System.out.println(x instanceof Number);// true
System.out.println(x instanceof Comparable);// true
assigment(=) operator
- 대입 연산자라고도 부름
- 변수에 값을 대입할 때 사용하는 이항 연산자이며 피연산자들의 결합 방향은 오른쪽에서 왼쪽임
- 자바에서 대입 연산자와 다른 연산자를 결합하여 만든 다양한 복합 대입 연산자를 제공함
연산자 |
설명 |
= |
왼쪽의 피연산자에 오른쪽의 피연산자를 대입 |
+= |
왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
-= |
왼쪽의 피연산자에서 오른쪽의 피연산자를 뺀 후 그 결괏값을 왼쪽의 피연산자에 대입 |
*= |
왼쪽의 피연산자에 오른쪽의 피연산자를 곱한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
/= |
왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후 그 결괏값을 왼쪽의 피연산자에 대입 |
%= |
왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후 그 나머지를 왼쪽의 피연산자에 대입 |
&= |
왼쪽의 피연산자를 오른쪽의 피연산자와 비트 AND 연산한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
|= |
왼쪽의 피연산자를 오른쪽의 피연산자와 비트 OR 연산한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
^= |
왼쪽의 피연산자를 오른쪽의 피연산자와 비트 XOR 연산한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
<<= |
왼쪽의 피연산자를 오른쪽의 피연산자만큼 왼쪽 시프트한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
>>= |
왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호를 유지하며 오른쪽 시프트한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
>>>= |
왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호에 상관없이 오른쪽 시프트한 후 그 결괏값을 왼쪽의 피연산자에 대입 |
int x;
int y = 4;
System.out.println(x = 10);// 10
System.out.println(x += y);// 14
System.out.println(x -= y);// 10
System.out.println(x *= y);// 40
System.out.println(x /= y);// 10
System.out.println(x %= y);// 2
System.out.println(x &= y);// 0
System.out.println(x |= y);// 4
System.out.println(x ^= y);// 0
System.out.println(x <<= y);// 0
System.out.println(x >>= y);// 0
System.out.println(x >>>= y);// 0
화살표(->) 연산자
- Java8부터 람다 표현식이 등장하면서 도입된 문법
- 익명 함수를 만들기 위해 사용
- FunctionalInterface 메소드를 구현할 때 주로 사용
// 기본
(parameters) -> { statements; }
// 파라미터는 0개 이상
() -> { statements; }
// 파라미터가 1개면 ( ) 생략 가능
parameter -> { statements; }
// statements가 하나면 { } 생략 가능, 이때 ; 도 생략 가능
(parameters) -> statement
3항 연산자
- 자바에서 유일하게 피연산자를 세 개나 가지는 조건 연산자
- 조건식 ? 반환값1 : 반환값2 -> 조건식이 참이면 반환값1을 반환, 거짓이면 반환값2를 반환
int x = 8;
int y = 10;
System.out.println(x > y ? "진실" : "거짓");// 거짓
연산자 우선순위
- 수식 내에 여러 연산자가 함께 등장할 때, 어느 연산자가 먼저 처리될 것인가를 결정함
우선순위 |
연산자 |
설명 |
1 |
(),[] |
괄호, 대괄호 |
2 |
!,~,++,-- |
부정, 증감 연산자 |
3 |
*,/,% |
곱셈, 나눗셈 연산 |
4 |
+,- |
덧셈, 빼기 연산 |
5 |
<<,>>,>>> |
비트 단위 쉬프트 연산자 |
6 |
<.<=,>,>= |
관계 연산자 |
7 |
==,!= |
관계 연산자 |
8 |
& |
비트 단위 논리 연산자 |
9 |
^ |
비트 단위 논리 연산자 |
10 |
&& |
논리곱 |
11 |
|| |
논리합 |
12 |
?: |
조건부 연산자 |
13 |
=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,~= |
대입 할당 연산자 |
(optional) Java 13.switch 연산자
- Java12부터 switch 연산자가 추가됨
- switch문의 변경이 아니라 새로운 switch 연산자가 추가된 것
//기존 스위치 문
String numStr = "One";
int result = 0;
switch(numStr){
case "One":
result = 1;
System.out.println(1);
break;
case "Two":
result = 2;
System.out.println(2);
break;
case "Three":
result = 3;
System.out.println(3);
break;
default:
System.out.println("default");
}
- 기존 스위치 문은 불필요하게 장황하며 가독성이 떨어지며 디버깅이 어려워짐
//Java12 switch 연산자
String numStr = "One";
int result = 0;
result = switch (numStr) {
case "One" -> 1;
case "Two" -> 2;
case "Three" -> 3;
default -> throw new IllegalStateException("error");
}
- Java12부터 람다 연산을 사용하여 가독성을 올릴 수 있음
//Java13 switch 연산자
String numStr = "One";
int result = 0;
result = switch(numStr) {
case "One" : yield 1;
case "Two" : yield 2;
case "Three" : yield 3;
default : throw new IllegalStateException("error");
};
- Java13부터 yield라는 산출값을 리턴 가능함
- break를 사용하지 않고 yield를 사용하여 변수에 값을 넣을 수 있음