목표
자바가 제공하는 다양한 연산자를 학습하세요.
학습할 것
- 산술 연산자 v
- 비트 연산자 v
- 관계 연산자 v
- 논리 연산자v
- instanceof v
- assignment(=) operator v
- 화살표(->) 연산자 v
- 3항 연산자 v
- 연산자 우선 순위 v
- (optional) Java 13. switch 연산자
1.산술 연산자
+ - * / %
사칙연산을 다루는 연산자로 , 가장 기본적이면서 가장 많이 사용되는 연산자 중 하나이다 . 산술 연산자는 모두 두 개의 피연산자를 가지는 이항 연산자이며 , 피연산자들의 결합 방향은 왼쪽에서 오른쪽이다.
항이란 해당 연산의 실행이 가능하기 위해 필요한 값이나 변수를 의미하며 이항 연산자란 해당 연산의 실행을 위해서 두개의 값이나 변수가 필요한 연산자를 의미한다 .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class Test1 {
public static void main(String[] args) {
int a = 10 ;
int b = 5;
int result;
// +
result = a + b ; // 15
// -
result = a - b ; // 5
// *
result = a * b ; // 50
// %
result = a % b ; //0
}
}
|
cs |
2.비트 연산자
연산이 되는 값들을 내부적으로 비트단위로 변경한 후 연산을 수행한다 .(10진수를 2진수로 바꿈)
정수 타입만 비트연산이 가능하고 , 실수형태는 연산이 불가능하다
& 비트 단위의 AND
| 비트 단위의 OR
^ 비트 단위의 XOR
~ 비트 반전(0은 1로 1은 0으로 바뀜)
& 비트 단위의 AND
0 0 -> 0
1 0 -> 0
0 1 -> 0
1 1 -> 1
&는 위의 방식으로 연산된다 둘다 같아야 1이 된다
ex) int a = 12 ;
int b = 20 ;
int result = a&b; <- result는 4가 담긴다 (비트단위로 연산후 10진수로 변환하여 값을 리턴한다.)
위의 a&b는 아래와 같이 동작한다 .
00000000 00000000 00000000 00001100 <- 12
&
00000000 00000000 00000000 00010100 <- 20
=
00000000 00000000 00000000 00000100 <- 4
| 비트 단위의 OR
0 0 -> 0
1 0 -> 1
0 1 -> 1
1 1 -> 1
OR는 위의 방식으로 연산된다 둘 중 하나라도 1이면 1이된다.
ex) int a = 12 ;
int b = 20 ;
int result = a|b; <- result는 4가 담긴다 (비트단위로 연산후 10진수로 변환하여 값을 리턴한다.)
위의 a&b는 아래와 같이 동작한다 .
00000000 00000000 00000000 00001100 <- 12
&
00000000 00000000 00000000 00010100 <- 20
=
00000000 00000000 00000000 00011100 <- 28
^ 비트 단위의 XOR
0 0 -> 0
1 0 -> 1
0 1 -> 1
1 1 -> 1
서로 반대여야만 1이 된다 서로같으면 0이된다
ex) int a = 12 ;
int b = 20 ;
int result = a^b; <- result는 4가 담긴다 (비트단위로 연산후 10진수로 변환하여 값을 리턴한다.)
위의 a&b는 아래와 같이 동작한다 .
00000000 00000000 00000000 00001100 <- 12
^
00000000 00000000 00000000 00010100 <- 20
=
00000000 00000000 00000000 00011100 <- 28
~ 틸트 연산자 ( 값을 반전시킴)
ex) int a = 12 ;
int b = 20 ;
int result = ~a;
위의 ~a는 아래와 같이 동작한다 .
00000000 00000000 00000000 00001100 <- 12
~
=
11111111 1111111111111111 11110011 <- -13
비트 이동 연산자 (<< , >> ,>>>)
- 비트 단위의 연산처리를 하며 자료의 가공을 위해 bit 값을 오른쪽 또는 왼쪽으로 이동하여 값에 대한 변화를 일으키는 연산자
1. x<<y : 정수 x의 비트를 y만큼 왼쪽으로 이동시킨다. (빈자리는 0으로 채워짐)
2. x>>y : 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다 (빈자리는 정수의 최상위 부호비트와 같은 값으로 채워진다. )
3. x>>>y: 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다 . (빈자리는 0으로 채워진다.)
예시)
2 << 3
00000000 00000000 00000000 00000010 <- 2
2 << 3는 아래와 같이 2를 32비트로 분해한 다음 왼쪽으로 3비트 이동시킨다
00000000000 00000000 00000000 00000010???
3비트가 왼쪽으로 이동 되었고 오른쪽 맨 끝 3자리가 비어졌다 . 이때 ???의 빈자리는 아래와 같이 0으로 채워진다.
00000000 00000000 00000000 00010000 <- 16
결과적으로 2진수로 표현된 2를 16으로 바뀌었다.
16>>3
00000000 00000000 00000000 00001000 <- 16
00000000 00000000 00000000 00000001000
이번에는 오른쪽으로 3비트가 이동되어서 오른쪽의 000이 아래와 같이 사라진다.
00000000 00000000 00000000 00000001 <- 2
위의 예시와 반대로 2진수로 표현된 16를 2으로 바뀌었다.
부호비트와 Int의 범위
int 값의 범위는 2진법으로 -2^31 ~2^31-1 이다 .
int 는 4byte 즉 32 비트를 사용한다. 32개의 bit 공간을 1로 채운다면 값은 10진수로 4,284,867,295가 된다.
하지만 위와 같이 사용할 경우 음수표현을 할 수없기 때문에 맨앞 자리를 부호로 사용하며 이를 부호비트라한다
0== 양수
1== 음수
3.관계 연산자
비교 연산자라고도 하며 수학에서의 부등호를 생각하면 된다. 관계연산자의 결과는 true 혹은 false 값인 boolean 타입으로 반환 된다. 제어문에서 많이 사용되는 연산자 이다.
연산자 | 기능 | 연산 예제 |
> | 왼쪽 항이 크면 참을, 아니면 거짓을 반환 | 3 >4 true |
< | 왼쪽 항이 작으면 참을 아니면 거짓을 반환 | 3<4 true |
>= | 왼쪽 항이 오른쪽 항 보다 크거나 같으면 참, 아니면 거짓 | 3 >= 4 false |
<= | 왼쪽 항이 오른쪽 항 보다 작거나 같으면 참 , 아니면 거짓 | 3 <= 4 true |
== | 두 개 항의 값이 같으면 참, 아니면 거짓을 반환 | 3 == 4 false |
!= | 두 개 항이 다르면 참, 아니면 거짓을 반환 | 3 != 4 false |
4.논리 연산자
논리 연산자는 AND(&&) , OR(||) , NOT(!) 세가지의 연산자가 있으며 관계연산자와 같이 사용 되는 경우가 많다 .논리 연산자 역시 연산의 결과가 true 혹은 false로 반환 된다
연산자 | 기능 | 연산 예제 |
&& | 두 항이 모두 참인 경우에만 결과 값이 참이다 .그렇지 않으면 거짓을 반환한다. | true&&true = true |
|| | 두 항 중 하난의 항만 참이면 결과 값은 참이다. 두항이 모두 거짓이면 결과 값은 거짓이다. | true || false = true |
! | 단항 연산자이다. 참인 경우는 거짓으로 바꾸고 , 거짓인 경우는 참으로 바꾼다. | !true = false |
* 단락회로평가(short circuit evaluation)
단락회로 평가는 논리 연산자를 사용할 때 고려해야 할 사항으로 두항 중 핲의 항에서 결과 값이 정해지는 경우 뒤의 값이 참인지 거짓인지 평가하지 않는 것을 말한다.
ex) int a = 10 ;
int b =3;
boolean c = ( ( a = a + 10 ) < 10 ) && ( ( b = b+2 ) <10 )
위의 연산 과정에서 단락회로평가가 이뤄지며 &&연산에서는 둘중 하나라도 false면 false 이고 , 첫번째 항에서 false 가 나왔기 떄문에 뒤의 연산은 따로하지 않는다 .
boolean d = ( ( a = a + 10 ) < 10 ) | | ( ( b = b+2 ) <10 )
위의 연산은 OR 연산이기 때문에 둘중 하나면 true여도 true가 나온다 이럴 경우에는 앞에서 false가 나와도 뒤의 값이 true가 나올 수 있기 때문에 단락회로 평가가 일어나지 않는다.
5.Instance of 연산자
참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아 보기 위해 instanceof 연산자를 사용한다. 주로 조건문에 사용되고 instanceof의 왼쪽에는 참조변수를 오른쪽에는 타입(클래스명) 이 피연산자로 위치한다. 그리고 연산의 결과로 boolean 값인 true , false 중의 하나를 반환한다 .
instancof를 이용하여 true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다
위의 그림을 예시로 intanceof 를 설명하면
Test2 는 Test1을 Test3는 Test2를 상속받고 있다.
Test 1의 메인메서드 안에서 Test1,Test2,Test3를 Test1의 메인메서드에서 생성한 후
instanceof로 검증해보면
test2 ,test3 두 변수 모두 Test1을 상속받기 때문에 true가 반환되고
아래와 같이 출력된다.
6. 대입연산자 (assignment(=) operator,할당연산자)
대입 연산자는 변수에 값을 대입할 때 사용하는 이항 연산자이며, 피연산자들의 결합 방향은 오른쪽에서 왼쪽이다 .
또한 , 자바에서는 대입 연산자와 다른 연산자를 결합하여 만든 다양한 복합 대입 연산자를 제공한다.
연산자설명
= | 왼쪽의 피연산자에 오른쪽의 피연산자를 대입함. |
+= | 왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
-= | 왼쪽의 피연산자에서 오른쪽의 피연산자를 뺀 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
*= | 왼쪽의 피연산자에 오른쪽의 피연산자를 곱한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
/= | 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
%= | 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 나머지를 왼쪽의 피연산자에 대입함. |
&= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 AND 연산한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
|= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 OR 연산한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
^= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 XOR 연산한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
<<= |
왼쪽의 피연산자를 오른쪽의 피연산자만큼 왼쪽 시프트한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
>>= | 왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호를 유지하며 오른쪽 시프트한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
>>>= | 왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호에 상관없이 오른쪽 시프트한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. |
* www.tcpschool.com/java/java_operator_assignment 표 참조
비트 연산자를 공부한 겸 한번 하나씩 해봤다. a 변수 선언한 것이 안나왔다 초깃값은 int a = 5 였다.
6.화살표(->) 연산자
람다함수를 만들때 사용되는 표현식이다 .
람다함수
2010년에 Project Lambda 라는 프로젝트로 진행되어 Java 8부터 공식 릴리즈 되었다 .
자바에는 함수의 개념이 없었다 이런 이유로 기존의 자바 언어 체계에서는 함수형 언어를 언어 차원에서 지원하지는 못하였다 .
때문에 , Java8에서 함수형 인터페이스 ( 단 하나의 메소드만이 선언된 이터페이스) 라는 개념을 도입하게 되었고 ,함수형 인터페이스의 경우 , 람다식으로 표현이 가능할 수 있게 제공하였다 .
Java8에서 함수형 인터페이스라는 개념과 람다 표현을 통해 입력에 의해서만 출려이 결정되도록 '순수한 함수' 를 표현할 수있게 되었고 , 람다식으로 표현함으로써 ' 익명함수 ' 를 정의할 수있게 되었다. 함수형 인터페이스의 메소드에서 또다른 함수형 인터페이스를 인자로 받을 수 잇도록 하여 '고계함수'를 정의할 수 있게 되었다 .즉, 함수형 프로그래밍 언어의 조건을 만족 시킬 수 있게 되었다
자바에서의 기본적인 람다식 구조
( int a , int b ) -> { return a + b }
특징
1.단순한 람다 구문의 경우 , 람다 구분에 중괄호가 없을 수도 있다 .
2.return 이 없을 수 도 있다 .
3.매개변수에는 타입을 명시하지 않아도 된다 .(타입 추론)
4.람다식 문법을 컴파일러가 익명 클래스로 변환한다. 즉 , 함수형 인터페이스를 컴파일러가 구현하도록 위임하는 형태라 할 수 있다.
람다 표현식 활용( 익명함수등 학습 후 다시 찾아보자.)
파라미터에 행위전달(Parameterized Behaviors)
메소드에 사용할 데이터 혹은 변수와 행위를 같이 전달하게 하여 메소드의 행위 부분도 분리할 수 있다.
-장점
-런타임에 행위를 전달 받아서 제어 흐름 수행(전략 패턴)
- 메소드 단위의 추상화가 가능
- 함수형 언어의 고차함수(Higher-Order Function)
불변 변수 사용 (Imumutable Free Variables)
자바에서 익명클래스 +자유 변수 포획으로 클러저를 가능하게 했는데 , 포획된 변수에서는 명시적으로 final 지시자를 사용하게 하였다. 람다식에서는 포획된 변수에 명시적으로 final 을 명시하지 않아도 포획된 변수는 변경할 수 없고 , 변경하는 경우 컴파일 에러가 발생한다.
변수의 변경이 불가능하다
Optional + Lamda 조합
java.util.Optional 이라는 클래스는 값이 있거나 없는 경우를 표현하기 위한 클래스로 map,filter ,flatMap 등의 고차 함수를 가지고 있다. Optional의 고차 함수를 조합하여 간결하게 표현이 가능하며 , 언제발생할지 모르는 NullPointerException으로 부터 자유롭다.
8. 3항 연산자
if else 구문을 표현하는 연산자 .
ex)
int a;
if(5<4) {
a=50
}else{
a=40
}
위의 if else 문을 삼항연산자로 표현하면 아래와 같다
int a =( 5<4 ) ? 50 : 40 ;
조건문? 참일 경우 리턴값 : 거짓일 경우 리턴값;
위와 같은 문법으로 구현된다.
코드라인 수를 줄일 수 있기 때문에 가벼운 로직을 처리한다면 삼항연산자로 처리하는 것이 좋다 .
주의 할 점은 삼항연산자를 사용하여 코드 라인이 줄어든다고 컴파일 속도가 빨라지는 것은 아니며
삼항연산자를 중복 사용할시 가독성이 떨어질 수 있으므로 중복처리는 피하는 것이 좋다.
9.연산자의 우선순위 ( 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 | = |
대입 연산자 및 복합 대입 연산자 (=, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, ^=, |=) |
오른쪽에서 왼쪽으로 |
*tcpschool.com/java/java_operator_arithmetic 에서 표 참조
10. switch 연산자 (Java 13) (스위치문 공부 후에 다시 조사)
참조
coding-factory.tistory.com/266 (3항연산자)
'JAVA' 카테고리의 다른 글
JAVA 스터디 5 - switch expression (자바 12부터 추가됨) (0) | 2021.02.05 |
---|---|
JAVA 스터디 4- 제어문,반복문 (0) | 2021.02.03 |
JAVA 스터디 2-자바 데이터 타입 , 변수 그리고 배열 (0) | 2021.02.02 |
JAVA 스터디 1-JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. (0) | 2021.01.31 |
JAVA 스터디 0 - 자바의특징 (0) | 2020.12.12 |