보근은 참고 있다
3주차 과제: 연산자 본문
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
산술 연산자
+ | 더하기 | int a = 6 + 5; // 11 |
- | 빼기 | int b = 6 - 5; // 1 |
* | 곱하기 | int c = 6 * 5; // 30 |
/ | 나누기 | double d = 6 / 5; // 1.2 |
% | 나머지 | int e = 6 % 5; // 1 |
이것들 외에도 ++, -- 등의 증감 연산자가 있다. 증감 연산자는 변수에 1을 더하거나 빼는 연산자인데, 위치마다 증감이 일어나는 시기가 다르다.
int a = 5;
int b = new int[2];
b[0] = a++; // b[0] = 5, a = 6.
b[1] = ++a; // b[1] = 7, a = 7.
위의 예시처럼 증감 연산자가 뒤에 붙어있으면 대입 연산이 끝나고 증감이 이뤄지고, 앞에 붙어있으면 증감이 된 후에 대입 연산이 이뤄진다.
그리고 +, - 같이 단항 연산자도 있다. 단항 연산자는 수의 부호를 바꾸기 위한 연산자이다. 위치는 변수 앞에 붙는다.
int positive = 5;
int negative = -5;
System.out.println(+positive); // 5
System.out.println(-positive); // -5
System.out.println(+negative); // -5
System.out.println(-negative); // 5
수학에서와 같이 양수에 양수를 붙여도 양수고, 음수에 양수를 붙여도 음수다.
비트 연산자
& | and | 두 비트가 모두 1일 때 1, 하나라도 0이면 0. |
| | or | 두 비트 중 하나라도 1이면 1, 둘 다 0일 때 0. |
~ | not | 1이라면 0, 0이라면 1. |
^ | exclusive or | 두 비트가 서로 다르면 1, 같으면 0. |
이 외에도 shift 연산이 있다. <<, >>, >>> 세 가지가 있다. 꺾쇠가 두 개인 애들은 shift 후에 비는 비트들을 부호 확장으로 채우고, 세 개인 애는 0으로 채운다.
양수는 >>이거나 >>>이거나 결과가 항상 같다. 음수는 >>>로 shift하면 양수가 된다.
이진수로 수를 계산한다는 것을 응용해 비트를 왼쪽으로 한 칸 밀면 2를 곱하고, 한 칸 오른쪽으로 당기면 2를 나누는 효과이다.
int a = 5 << 2; // 20.
int b = 33 >> 4; // 2.
int c = 31 >>> 4; // 1.
int d = Integer.MIN_VALUE >>> 1 // 2^30.
관계 연산자
< | 좌우를 비교해 우가 더 크면 true, 반대면 false | 3 < 5 // true 6 < 3 // false |
> | 좌우를 비교해 좌가 더 크면 true, 반대면 false | 5 > 3 // true 3 > 6 // false |
>= | 좌우를 비교해 우가 더 크거나 같으면 true, 작으면 false | 5 >= 5 // true 3 >= 5 // false 7 >= 5 // true |
<= | 좌우를 비교해 좌가 더 크거나 같으면 true, 작으면 false | 3 <= 3 // true 5 <= 3 // false 1 <= 3 // true |
== | 좌우가 같으면 true, 다르면 false | (2+3) == 5 // true (2+2) == 5 // false |
!= | 좌우가 다르면 true, 같으면 false | (2+3) != 5 // false (2+2) != 5 // true |
레퍼런스 타입을 비교할 때 관계 연산자는 예상과 다르게 결과가 나올 수도 있다. 객체의 값을 비교하려면 Object의 eqauls() 메소드를 사용해야 정확하게 비교가 되고, 위의 관계 연산자를 사용하면 두 객체가 같은 인스턴스를 참조하고 있는지에 대한 결과가 반환된다.
논리 연산자
& | 논리곱 | true & true; // true false & false; // false true & false; // false |
| | 논리합 | true | true; // true false | false; // false true | false; // true |
! | 부정 | !true; // false !false; // true |
&& | 조건부 논리곱 | true && true; // true false && false; // false true && false; // false |
|| | 조건부 논리합 | true || true; // true false || false; // false true || false; // true |
조건부 논리 연산자와 그냥 논리 연산자는 결과는 같다. 두 개짜리 애들은 첫 번째 항에서 이미 결과가 결정되면 두 번째 항은 쳐다도 안 본다. 예를 들어, &&에 첫 번째 항이 이미 false라면 두 번째 항의 결과랑 상관없이 false이므로, 두 번째 항은 확인 없이 결과를 반환한다. 하지만 하나 짜리 애들은 그런 거 신경 안쓰고 뒤에 것까지 확인을 다 한 뒤에 결과를 반환한다.
public static void main(String[] args) {
if(getTrue() || getFalse()) { // 두 개짜리, 조건부 논리 연산자.
System.out.println("Hello");
}
System.out.println("==========");
if(getTrue | getFalse()) { // 한 개짜리, 그냥 논리 연산자.
System.out.println("Bye");
}
}
static boolean getTrue() {
System.out.println("true!!!");
return true;
}
static boolean getFalse() {
System.out.println("false!!!");
return false;
}
/* 결과는
true!!!
Hello
==========
true!!!
false!!!
Bye
*/
instanceof
instatnceof 연산자는 왼쪽의 객체나 배열의 값이 오른쪽 타입으로 형변환이 가능하다면 true, 아니라면 false를 반환한다. 만약 왼쪽의 값으로 null이 온다면 false가 반환된다. 왼쪽 항에는 프리미티브 타입의 값이 올 수 없고, 레퍼런스 타입의 객체가 와야한다. 오른쪽 항에는 클래스나 인터페이스 등의 레퍼런스 타입이 와야한다.
Parent p = new Parent();
Son s = new Son();
if (p instanceof Son) { // false.
...
}
else if (s instanceof Parent) { // true.
...
}
assignment(=) operator
할당 연산자는 왼쪽 항, 변수에 오른쪽 항, 값이나 인스턴스를 저장하거나 할당하는 연산자이다. 왼쪽에는 로컬 변수, 배열 변수, 객체 변수가 올 수 있다. 오른쪽에는 그 타입에 맞는 적절한 값이 와야한다.
= | 왼쪽 항에 오른쪽 항의 값이나 인스턴스를 할당한다. | int a = 5; char[] c = new char[3]; Object o = new Object(); |
+= | 왼쪽 항에 왼쪽 값과 오른쪽 값의 합을 할당한다. | int i = 3; i += 5; // 8 |
-= | 왼쪽 항에 왼쪽 값과 오른쪽 값의 차를 할당한다. | int i = 3; i -= 5; // -2 |
*= | 왼쪽 항에 왼쪽 값과 오른쪽 값의 곱을 할당한다. | int i = 3; i *= 5; // 15 |
/= | 왼쪽 항에 왼쪽 값을 오른쪽 값으로 나눈 값을 할당한다. | int i = 8; i /= 5; // 1 |
%= | 왼쪽 항에 왼쪽 값을 오른쪽 값으로 나눈 나머지를 할당한다. | int i = 8; i %= 5; // 3 |
<<= | 왼쪽 항의 비트를 오른쪽 값만큼 left shift하고 왼쪽 항에 값을 할당한다. | int i = 2; i <<= 2; // 8 |
>>= | 왼쪽 항의 비트를 오른쪽 값만큼 right shift하고 왼쪽 항에 값을 할당한다. | int i = 10; i >>= 2; // 2 |
>>>= | 왼쪽 항의 비트를 오른쪽 값만큼 unsigned right shift하고 왼쪽 항에 값을 할당한다. | int i = Integer.MIN_VALUE; i >>>= 31; // 1 |
&= | 왼쪽 항을 오른쪽 값으로 & 비트 연산하고 왼쪽 항에 값을 할당한다. | int i = 15; i &= 42; // 10 |
|= | 왼쪽 항을 오른쪽 값으로 | 비트 연산하고 왼쪽 항에 값을 할당한다. | int i = 15; i |= 42; // 47 |
^= | 왼쪽 항을 오른쪽 값으로 ^ 비트 연산하고 왼쪽 항에 값을 할당한다. | int i = 15; i ^= 42; // 37; |
화살표(->) 연산자
화살표 연산자는 람다식을 표현할 때 사용한다. 연산자의 왼쪽에는 파라미터들이, 오른쪽에는 함수 블럭이 들어간다. 파라미터는 없을 수도 있고 무수히 많을 수도 있으며, 콤마로 분리한다. 파라미터가 하나라면 괄호를 생략할 수 있다.
interface Calculator {
int cal(int num1, int num2);
}
public static void main(String[] args) {
Calculator big = (x, y) -> {
if(x > y) return x;
else return y;
};
System.out.println(big.cal(5, 6)); // 6
}
3항 연산자
3항 연산자는 if-else의 연산자 버전 느낌이다. 이름처럼 항이 3개가 나오며 (조건) ? (참일 때 값) : (거짓일 때 값)의 구조이다. 조건이 true 라면 첫 번째 값이, false라면 두 번째 값이 반환된다. 첫 번째 항은 boolean 타입이 와야하고, 두 번째, 세 번째 항은 뭐든 상관 없지만 같은 타입으로 와야한다.
int a = 5, b = 3;
int big = (a > b) ? a : b; // big = a;
연산자 우선 순위
1 | ++, -- | 증감 연산자 |
+, - | 단항 연산자 | |
~ | 비트 연산자 | |
! | 논리 연산자 | |
2 | *, /, % | 산술 연산자 |
3 | +, - | 산술 연산자 |
4 | <<, >>, >>> | 비트 연산자 |
5 | <, <=, >, >= | 논리 연산자 |
instanceof | instanceof | |
6 | ==, != | 관계 연산자 |
7 | & | 비트 연산자 |
& | 관계 연산자 | |
8 | ^ | 비트 연산자 |
^ | 관계 연산자 | |
9 | | | 비트 연산자 |
| | 관계 연산자 | |
10 | && | 조건부 관계 연산자 |
11 | || | 조건부 관계 연산자 |
12 | ? : | 삼항 연산자 |
13 | =, +=, -=, *=, /=, %=, <<=, >>=, >>>= | 대입, 할당 연산자 |
14 | -> | 화살표 연산자 |
'Language > 자바 정리 할래' 카테고리의 다른 글
6주차 과제: 상속 (0) | 2020.12.21 |
---|---|
5주차 과제: 클래스 (0) | 2020.12.19 |
4주차 과제: 제어문 (0) | 2020.12.12 |
2주차 과제: 자바 데이터 타입, 변수 그리고 배열 (0) | 2020.11.18 |
1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. (0) | 2020.11.10 |