Java는 백기선님의 유튜브를 통해 공부한다.
목표
자바가 제공하는 다양한 연산자를 학습하세요.
학습할 것
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
연산자(Operater)
연산자는 하나, 둘 또는 세 개의 피연산자에 대해 특정 연산을 수행한 다음 결과를 반환하는 특수 기호이다. 연산자는 각 기호별로 다양한 연산자들이 존재하는데 수학의 연산자들중 곱셈을 덧셈보다 먼저하듯이
각 연산자끼리의 연산 우선 순위가 정해져있다.
- 연산자 우선 순위
최우선 연산자
( )
: 우선순위 변경을 위해사용[ ]
: 배열의 크기나 첨자를 나타낼 때 사용
단항(Unary)연산자
단항 연산자에는 피연산자가 하나만 필요하다. 값 1 씩 증가 / 감소, 표현식 부정 또는 부울 값 반전과 같은 다양한 작업을 수행한다.
- 연산자
+
// 단항 더하기 연산자. 양수값을 나타냄 (하지만 이것이 없으면 양수 임).-
// 단항 빼기 연산자. 2의보수 연산자 or 부호바꿈연산자++
// 증가 연산자. 값을 1 씩 증가 (왼쪽 오른쪽 둘다 가능 -> 위치에 따라 값이 다름)--
// 감소 연산자. 값을 1 씩 감소 (왼쪽 오른쪽 둘다 가능 -> 위치에 따라 값이 다름)!
// 부울대수 NOT(true -> false, false -> true)~
// 1의 보수를 구해주는 연산자.- 양수의 1의 보수의 부호는 음수가 되고 절대값 1증가
- 음수의 1의 보수의 부호는 양수가 되고 절대값 1감소
단항 연산자 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Unary
{
public static void main(String args[]) {
int a = 10, b = -10;
boolean c = true, d = false;
System.out.println("a= " + a + "\t b=" + b + "\t c=" + c + "\t d=" + d);
System.out.println("~a=" + ~a); // -11 1의 보수 연산(양수-> 음수 부호가 바뀌고 1증가됨)
System.out.println("~b=" + ~b); // 9 음수-> 양수 부호가 바뀌고 1감소됨
System.out.println("!c=" + (!c) + "\t !d = " + (!d)); // true -> false, false -> true
System.out.println("+a=" + (+a) + "\t +b = " + (+b)); // '+'는 형식적 제공
System.out.println("-a= " + (-a) + "\t -b = " + (-b));
// '-'는 2의보수 연산자 or 부호바꿈연산자
}
}
단항 연산자 결과
증감연산자 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Operator
{
public static void main(String args[])
{
int a = 10, b = 5;
System.out.println("a = " + a +"\t b = " + b);
++a;
--b;
System.out.println("a = " + a +"\t b = " + b);
a++;
b--;
System.out.println("a = " + a +"\t b = " + b);
// 증감을 하기 전에 명령문을 먼저 처리하므로 10 출력
System.out.println("후위 연산 a = " + a++);
// 명령문이 처리후 증감한 a값 확인
System.out.println("a 증가 = " + a);
// 증감을 한 후에 명령문을 처리하므로 11 출력
System.out.println("전위 연산 a = " + ++a);
}
}
증감 연산자 결과
산술연산자
+
// 더하기 연산자 (문자열 연결에도 사용됨)-
// 빼기 연산자*
// 곱셈 연산자/
// 나눗셈 연산자%
// 나머지 연산자 ( A % B = A를 B로 나눈 나머지)
산술연산자 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Operator
{
public static void main(String args[])
{
byte a = 10;
byte b = 20;
//byte c = a + b; 일경우 a, b 모두 int 형으로 변환 되어 연산 되기 때문에 에러 발생.
byte c = (byte)(a + b); // 형변환을 통해 byte 데이터 타입으로 바꿔주고 계산해야 한다.
System.out.println(c);
}
}
- 결과값 30
비트 시프트 연산자
- x
<<
y : 정수 x의 각 비트를 y만큼 왼쪽으로 이동. (빈자리는 0으로 채워짐) - x
>>
y : 정수 x의 각 비트를 y만큼 오른쪽으로 이동. (빈자리는 정수 x의 최상위 부호비트와 같은 값으로 채워짐.) - x
>>>
y : 정수 x의 각 비트를 y만큼 오른쪽으로 이동. (빈자리는 0으로 채워짐)
비트시프트연산자 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Operator
{
public static void main(String args[])
{
int temp;
System.out.println(8);
System.out.println(Integer.toBinaryString(8));
temp = 8 >> 2;
System.out.println( "8 >> 2 = " + temp);
System.out.println(Integer.toBinaryString(temp));
System.out.println(-8);
System.out.println(Integer.toBinaryString(-8));
temp = -8 <<2;
System.out.println("-8 << 2 = " + temp);
System.out.println(Integer.toBinaryString(temp));
System.out.println(-8);
System.out.println(Integer.toBinaryString(-8));
temp = -8 >> 2;
System.out.println( "-8 >> 2 = " + temp);
System.out.println(Integer.toBinaryString(temp));
System.out.println(-8);
System.out.println(Integer.toBinaryString(-8));
temp = -8 >>> 2;
System.out.println( "-8 >>> 2 = " + temp);
System.out.println(Integer.toBinaryString(temp));
}
}
비트시프트 결과
관계연산자
두 항의 크기,값을 비교하는 연산자.
연산의 값은 true, false
<
,>
,<=
,>=
: 두 피 연산자의 크기를 비교(boolean형을 제외한 나머지 자료형 사용가능)==
,!=
: 두 피연산자의 값이 같은지 비교
논리연산자
논리연산자는 이항 연산자로 조건의 참, 거짓을 비교하는 조건 논리 연산자와 비트 논리 연산자로 나뉜다.
조건 논리 연산자 (||
, &&
) : boolean형의 값을 결과로 하는 조건식만 허용 (조건문, 반복문에서 많이 사용된다.) ||
은 OR 결합이고 &&
은 AND결합이다.
비트 논리 연산자(|
,&
,^
,~
) : 피연산자끼리 이진 비트 연산을 수행해서 결과를 정수로 반환하는 연산자 (정수형만 사용가능) * |
은 OR연산자, &
은 AND연산자, ^
은 XOR연산자, ~
은 NOT연산자이다. * OR 둘 중 하나라도 1 이면 OR값은 1 * AND 둘 중 하나라도 0 이면 혹은 둘 다 1이면 AND값은 0 * XOR 둘이 같으면 0 다르면 1
논리연산자 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Operator
{
public static void main(String args[])
{
boolean pan;
int x = 3;
int y = 5;
pan = 10 > 3 && 3 < 10; // (10 > 3 = true) AND (3 < 10 = true) = true
System.out.println("pan:" + pan);
pan = 10 > 3 || 3 < 10; // (10 > 3 = true) OR (3 < 10 = true) = true
System.out.println("pan:" + pan);
System.out.println("x는 " + x + "이고, y는 " + y + "일때, ");
System.out.println("x | y = " + (x | y)); // ( 11 과 101 OR연산)
System.out.println("x & y = " + (x & y)); // ( 11 과 101 AND연산)
System.out.println("x ^ y = " + (x ^ y)); // ( 11 과 101 XOR연산)
System.out.println("~x = " + ~x); // ( 11 NOT)
System.out.println("true | false = " + (true | false));
System.out.println("true & false = " + (true | false));
System.out.println("true ^ false = " + (true ^ false));
}
}
논리연산자 결과
instanceof 연산자
참조변수가 참조하고 있는 ‘인스턴스’의 실제 타입을 알아보기 위해 instanceof 연산자를 사용한다.
주로 조건문에 사용되며, instanceof의 왼쪽에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치한다.
그리고 연산의 결과로 boolean값인 true, false 중의 하나를 반환한다.
instanceof를 이용한 연산결과로 true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.
즉, 왼쪽 참조변수(인스턴스)가 오른쪽 타입(클래스)로 형변환이 가능한지(클래스에 속하는지)에 대해 연산하는 연산자이다. 또한, true false 값을 나타내기 때문에 조건문을 사용한다.
값이 null인 참조변수에 대해 instanceof 연산을 수행하면 flase를 결과로 얻는다.
obj1,2의 instanceof 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Operator {
public static void main(String[] args) {
Parent obj1 = new Parent();
Parent obj2 = new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
System.out.println("obj1 instanceof MyInterface: "
+ (obj1 instanceof MyInterface));
System.out.println("obj2 instanceof Parent: "
+ (obj2 instanceof Parent));
System.out.println("obj2 instanceof Child: "
+ (obj2 instanceof Child));
System.out.println("obj2 instanceof MyInterface: "
+ (obj2 instanceof MyInterface));
}
}
class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}
instanceof 결과
assignment(=) operator(대입연산자)
대입 연산자는 2항 연산자로 좌측 피연산자에 우측 피연산자를 연산후 대입하는 연산자이다. 예를 들어
1
2
i = 10; // 변수 i에 10을 대입
i += 10 // 변수 i에 10을 더한 후 대입 i의 초기값이 10이었다면 10+10 이 i 즉, i의 값은 20이 된다.
대입 연산자의 종류로는
1
2
3
4
5
6
7
8
9
10
x += y; // x = x+y
x -= y; // x = x-y
x *= y; // x = x*y
x /= y; // x = x/y
x %= y; // x = x%y
x <<= y; // x = x<<y
x >>= y; // x = x>>y
x &= y; // x = x&y
x ^= y; // x = x^y
x |= y; // x = x!y
등이 있다.
화살표(->) 연산자(람다)
자바8 에서 부터 화살표 즉, 람다 연산자가 추가되었는데 람다식이란 “식별자없이 실행가능한 함수”이다.
함수인데 함수를 따로 만들지 않고 코드한줄에 함수를 써서 그것을 호출하는 방식이다.
람다의 장단점
장점
람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을 단순하게 표현 가능
람다는 지연연상을 수행 함으로써 불필요한 연산을 최소화 가능
멀티쓰레디를 활용하여 병렬처리를 사용 가능
단점
람다식의 호출이 까다로움
람다 stream 사용 시 단순 for문 혹은 while문 사용 시 성능하락
불필요하게 너무 사용하게 되면 오히려 가독성이 떨어진다.
람다식 사용법
1
(매개변수, ...) -> { 실행문 ... }
왼쪽에 메소드(또는 함수)에서 사용 할 매개변수를 나열한다.
예를 들어
1
2
3
4
5
6
7
8
9
10
@FunctionalInterface
interface Say{
int someting(int a,int b);
}
class Person{
public void hi(Say line) {
int number = line.someting(3,4);
System.out.println("Number is "+number);
}
}
예를들기 위해 Person이라는 Class와 Say라는 Functional Interface를 만들었다.
Functional Interface란 함수가 하나만 존재하는 Interface를 의미한다.
원래는 다음과 같이 작성하지만
1
2
3
4
5
6
7
8
9
Person rin = new Person();
rin.hi(new Say() {
public int someting(int a, int b) {
System.out.println("My Name is Coding-Factory");
System.out.println("Nice to meet you");
System.out.println("parameter number is "+a+","+b);
return 7;
}
});
람다를 사용하게 되면
1
2
3
4
5
6
7
Person rin = new Person();
rin.hi((a,b) ->{
System.out.println("This is Coding-Factory!");
System.out.println("Tank you Lamda");
System.out.println("parameter number is "+a+","+b);
return 7;
});
이렇게 표현할 수 있다.
매개 변수가 하나라면 ()소괄호를 생략가능
실행문이 한 문장이라면 {}중괄호도 생략가능
람다식 예제
- 두개의 숫자 더하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface Compare{
public int compareTo(int a, int b);
}
public class Ramda2 {
//람다식 문법 (매개변수 목록)->{실행문}
public static void exec(Compare com) {
int k = 10;
int m = 20;
int value = com.compareTo(k, m);
System.out.println(value);
}
public static void main(String[] args) {
exec((i,j)->{
return i+j;
});
}
}
- 결과값 30
- 두개의 숫자중 큰 수 찾기
1 2 3 4 5 6 7 8 9 10 11
import extendsss.main; public class Ramda3 { @FunctionalInterface//함수형 인터페이스 체크 어노테이션 public interface MyNumber{ int getMax(int num1, int num2); } public static void main(String[] args) { MyNumber max = (x,y)->(x>=y)? x:y; System.out.println(max.getMax(10, 30)); } }
- 결과값 30
- Runnable 인스턴스 생성
1 2 3 4 5 6 7 8 9 10 11
public class RunnableEx { public static void main(String[] args) { Runnable runnable = () -> { for (int i = 0; i < 30; i++) { // 조건 : i가 30 보다 작으면 실행 System.out.println(i); } }; Thread thread = new Thread(runnable); thread.start(); } }
- 결과값 0 1 2 3 . . . 28 29
3항 연산자
1
2
3
int a = (5<4) ? 50 : 40;
// 조건문 ? 참일때 : 거짓일떄
System.out.println(a);
조건문의 참과 거짓에 따라 변수 a 에 담기는 값이 변하게 된다.
결과는 거짓이므로 40이 출력된다.
Java 13. switch 연산자
Java12부터 switch 연산자가 추가 되었다.
기존에 switch문이 변경된것이 아니라 switch 연산자가 추가 된것이다.
switch 문(statement)
- 다수의
case
,break
가 존재하게 된다. break;
를 빼먹을 경우 다음 분기로 넘어가게 됨.return
값이 존재할수없다.
Switch 연산자(operator)
break;
를 사용하지 않아도 된다.yield
존재함return
값 존재해도됨case -> A
같은 형식으로 표현가능
switch의 반환값이 따로 필요하지 않거나 case가 switch 들어오는 모든 인자를 커버하는 경우
default 항목을 넣어주지 않아도 되나 그렇지 않은 경우는 default -> code
를 작성해야 한다.
Java12
->
(화살표) 표현이 가능하고 data만 존재할 경우return
이 가능하다.->
구문을 사용할 경우break;
를 적지 않아도 다음case
구문으로 넘어가지 않는다.->
표현 오른쪽은 꼭 단일 수행일 필요는 없다. 블록{}
안에서의 작업도 가능하다.
Java13
yield
예약어가 추가됨.yield x
하게 되면x
가 리턴됨.yield
는 예약어이지만 변수명으로 사용가능하다.int yield = 3;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Main {
public static void main(String[] args) {
//Java 12 이전
int num = 1;
int returnNum = 0;
switch(num){
case 1:
returnNum = 1;
System.out.println("1들어옴");
break;
case 2:
returnNum = 2;
System.out.println("2들어옴");
break;
case 3:
returnNum = 3;
System.out.println("3들어옴");
break;
}
System.out.println("returnNum : [ " + returnNum + " ]");
//Java 12
returnNum = switch(num){
case 1 -> 1;
case 2 -> 2;
default -> throw new IllegalStateException("Unexpected value: " + num);
};
System.out.println("returnNum : [ " + returnNum + " ]");
//Java13
returnNum = switch(num){
case 1 : yield 3;
default : throw new IllegalStateException("unexpected value : " + num);
};
System.out.println("returnNum : [ " + returnNum + " ]");
}
}
- 결과
1 2 3 4
1들어옴 returnNum : [ 1 ] returnNum : [ 1 ] returnNum : [ 3 ]