연산자(Operator)
- 연산을 수행하는 기호이다.
- 연산을 수행하기 위해선 대상, 바로 '피연산자'가 필요하다.
산술 연산자
- 산술연산자는 +, -, *, /, %로 이루어져있다.
- 정수끼리 연산을 하면, 피연산자 중에 long이 있을경우에는 long으로 변환 후 수행, 그 외의 정수는
int로 변환된후 실행된다.
- 산술 연산자의 오버플로우
- 오버플로우(Overflow)는 변수가 자신이 표현할 수 있는 범위를 벗어나는 값을 가지게 되는 상항을 말한다.
연산자의 부분에서는 더하기나 곱하기등을 통해 표현할수있는 최대값을 벗어나면
오버플로우가 발생한다.
- 오버플로우(Overflow)는 변수가 자신이 표현할 수 있는 범위를 벗어나는 값을 가지게 되는 상항을 말한다.
public class Main {
public static void main(String[] args) {
int a = 1000000; // 1,000,000
int b = 1000000; // 1,000,000
int result = a * b;
System.out.println("곱셈 결과: " + result); //곱셈 결과: -727379968, 오버플로우 발생
}
}
- 부동 소수점
- 부동소수점은 실수를 표현하는 방식 중 하나이다.
부동소수점은 이진법으로 표현할때 정확히 표현되지 않는 값들이 존재한다.
제대로 표현되는 값은 분모가 2의 거듭제곱을 사용하는 0.5(2분의1), 0.25(4분의 1), 0.125(8분의 1)
과 같고 나머지는 정확히 표현할수가 없어 무한소수가 되어 근사치로 표현된다.
아래 코드를 보면 0.3이 아니라 0.3......4 가 나오게 된다.
- 부동소수점은 실수를 표현하는 방식 중 하나이다.
public class Main {
public static void main(String[] args) {
double num1 = 0.1;
double num2 = 0.2;
double result = num1 + num2;
System.out.println("결과: " + result); // 예상: 0.3, 실제: 0.30000000000000004
}
}
따라서 이것을 해결할려면 'BigDecimal'과 같은 클래스를 사용하여 정확한 실수 연산을 해야한다.
비트 연산자
- 비트 연산자는 말 그대로 비트 단위로 연산이 이루어지는 연산자이다.
데이터가 컴퓨터 내부에서 0과 1로 이루어져있기때문에 비트연산자라고 부른다. 그만큼 빠른 속도로 계산한다. - 비트 연산자는 &, |, ^, ~, <<, >>, >>> 등으로 이루어져있다.
- I(OR연산자) : 피연산자 중 한 쪽의 값이 1이면, 1을 결과로 얻는다.
- &(AND연산자): 피연산자 양 쪽의 값이 모두 1이어야만 1을 결과로 얻는다.
- ^(XOR연산자): 피연산자의 값이 서로 다를때만 1을 결과로 얻는다.
- ~(비트 전환 연산자): 비트 값을 0은 1로, 1은 0으로 바꾸는 연산자이다.
int num = 5;
int result = ~num;
System.out.println(result); //-6이 출력이 된다.
//num = 00000101
//~num = 11111010
- << >> 시프트 연산자의 의미는 다음과 같다.
- << 왼쪽 시프트 연산자 경우: 피연산자의 비트를 왼쪽으로 이동시킨다.
- >>오른쪽 시프트 연산자 경우: 피연산자의 비트를 오른쪽으로 이동시키는 연산을 수행한다.
- 사용예시, 00101 -> 0010100 가 된다. 따라서 5->20
public class LeftShiftExample {
public static void main(String[] args) {
int num = 5; // 5는 이진수로 00000101
int result = num << 2; //왼쪽으로 2비트 이동
System.out.println("원래 값: " + num); // 5
System.out.println("시프트 결과: " + result); // 20 (00010100)
}
}
관계 연산자
- 비교 연산자라고도 하며 결과는 true 혹은 false, boolean 자료형으로 반환된다.
아래는 관계연산자의 종류이다.
보통 조건절로 사용할때 많이 쓰인다고 생각하면 된다.
논리 연산자
- 논리 연산자도 연산 결과가 true 혹은 false, boolean형으로 반환된다.
- 논리 연산자는 AND(&&), OR(||), NOT(!) 세가지가 있다.
아래는 대입연산자 종류와 기능이다.
예시 코드를 들면 다음과 같다.
System.out.println(5>3); //true 관계 연산자
System.out.println(5>3&&5>4); //true 두 항 모두 다 참이므로 true
System.out.println(5>3&&5>10); //false 두 항중 오른쪽 항이 거짓이므로 false
System.out.println(5>3||5>10); //true 두 항중 오른쪽 항이 참이므로 false
//조건문에서 논리연산자를 여러번 사용할경우 앞쪽에서 이미 false가 뜨면 뒤에 논리는 보지않는다.
//활용가능한 부분: bfs 같은 너비탐색에서 상하좌우 노드 탐색하는경우 visited[i][j] 가 i가 음수로 범위를 벗어나는 오류 뜰수있으나 앞에가 false면 짤린다.
if(i>=0&&i<N&&j>=0&&j<N&&visited[i][j]) //이미 i나 j에 음수가 들어가거나 범위 밖을 넘어가면 조건문이 종료된다.
- 추가로 설명할 부분은 논리연산자중 &&, ||는 왼쪽부터 참인지 거짓인지 판단하게 되는데 &&왼쪽이 거짓이경우 오른쪽 항을 보지도 않고 false로 리턴한다. ||의 경우도 왼쪽이 참일경우 오른쪽항 판단하지않고 true로 리턴한다. 그래서
위에 코드 마지막 부분처럼 사용이 가능하다.
- '||'와 '|'의 다른점은 |는 왼쪽항의 결과와 상관없이 오른쪽 항도 체크를 한다는것이다. 물론 그만큼 시간적으로는 더 걸리는게 사실이나 2개를 다 확실히 체크할 일이 있을경우에는 '|'쓰는것이 좋다.
instanceof
- 객체 타입을 확인하는 연산자이다.
- 형변환 가능여부를 확인하며 true/false로 결과를 반환한다.
- 주로 상속 관계에서 부모객체인지 자식 객체인지 확인하는데 사용된다.
밑에 코드를 통해 더 자세히 설명하겠다.
class Parent{}
class Child extends Parent{}
public class Main {
public static void main(String[] args){
Parent parent = new Parent();
Child child = new Child();
System.out.println( parent instanceof Parent ); // true, 부모가 부모클래스 소속이므로 true
System.out.println( child instanceof Parent ); // true, 자식은 부모클래스로부터 상속받은 자식클래스 소속이므로 true
System.out.println( parent instanceof Child ); // false, 자식이 부모로부터 상속받은거지 상속한게 아니므로 false
System.out.println( child instanceof Child ); // true, 자식은 자식클래스로부터 나온것이므로 true
}
}
assignment(=) operator
- 대입연산자라고 하며 변수에 값을 대입할때 사용하는 이항 연산자이다.
- 피연산자들의 결합 방향은 오른쪽에서 왼쪽이다.
- 대입연산자의 종류
- 예시 코드 작성
int num1 = 10;
int num2 = 5;
num1 += num2; //15
num1 -= num2; //5
num1 *= num2; //50
num1 /= num2; //2
num1 %= num2; //0
num1 <<= 2; //40
num1 &= 10; //1
화살표(->) 연산자
- 자바 8에서 람다 표현식이 추가됨에 따라 등장한 연산자이다.
- 아래 예시를 통해 나타내보겠다.
자바 8 이전의 인터페이스와 구현 클래스
// 인터페이스 선언
interface MyInterface {
void doSomething();
}
// 인터페이스를 구현하는 클래스
class MyClass implements MyInterface {
@Override
public void doSomething() {
System.out.println("Doing something in MyClass.");
}
}
화살표 연산자와 람다식을 활용한 구현(메인에서 바로 구현후 사용)
// 함수형 인터페이스 선언
interface MyFunctionalInterface {
void doSomething();
}
public class Main {
public static void main(String[] args) {
// 람다 표현식과 화살표 연산자를 활용한 메서드 구현
MyFunctionalInterface myFunc = () -> System.out.println("Doing something with Lambda.");
//메서드 호출
myFunc.doSomething();
}
}
근데 이제 MyFunctionalInerface가 반드시 단 하나의 메서드를 가져야만 사용할 수 있다. 아니면 어떤 메서드를
호출하는지를 알 수가 없다.
3항 연산자
- 삼항 연산자는 세개의 피연산자를 통해 If문을 간략하게 처리한다.
코드로 예시를 들겠다. 10>5가 성립하면 num = 10; 아니면 num = 5가된다는 가정으로 코드를 짜봤다.
원래의 if문
int num;
if(10>5)num = 10;
else num = 5;
삼항 연산자 사용
int num = (10>5)?10:5; //int num = (조건)? 조건true일시 발동: 조건 false일시 발동;
- 삼항 연산자가 식을 간략하게 해주지만 계산속도가 빨라지는 것은 아니다.
연산자 우선 순위
- 식에 여러개의 연산자가 있는 경우 우선순우가 높은 연산자를 먼저 처리한다.
- 우선순위가 동일하면 왼쪽에서 오른쪽으로 순서대로 처리한다.
Java 13. switch 연산자
- 13에 swtich 연산자 기능이 추가 되기전
- 다수의 case,break 존재
- break; 를 빼먹을 경우 다음분기로 넘어간다
- return값이 존재할 수 없다.
- 13에 switch 연산자 기능이 추가 되고난 후(변경이 아니다, 기존 switch문에 기능이 추가된거다)
- break 대신 yield사용(return값 존재)
- case -> A 같은 형식으로 표현가능
- case가 모든 인자를 커버하는 경우 default 항목을 넣어주지 않아도 되나 그렇지 않은 경우는 default -> code를 작성해야한다.
기존 방식
char c = 'B';
int grade = 0;
switch (c){
case 'A':
grade = 4;
break;
case 'B':
grade = 3;
break;
case 'C':
grade = 2;
break;
case 'D':
grade = 1;
break;
}
Java 13 에서 나온 기능 활용 표현식
char c = 'B';
int grade = switch (c){
case 'A': yield 4;
case 'B': yield 3;
case 'C': yield 2;
case 'D': yield 1;
default : throw new IllegalStateException("Invalid grade: " + c);
}
※참고로 예약어는 변수명으로 사용불가능하지만 yield는 예외이다. 예약어로 사용가능하다.
참고
- 연산자
자바의 정석(저자: 남궁성) - 비트 연산자
https://staticclass.tistory.com/25 - 관계연산&논리연산
https://velog.io/@foeverna/Java-%EC%97%B0%EC%82%B0%EC%9E%90-%EA%B4%80%EA%B3%84-%EB%85%BC%EB%A6%AC-%EC%A1%B0%EA%B1%B4-%EB%B9%84%ED%8A%B8-%EC%97%B0%EC%82%B0%EC%9E%90 - 연산자 우선순위
https://danmilife.tistory.com/12 - 자바 13 swtich 연산자
https://babgeuleus.tistory.com/84#Java%2013.%20switch%20%EC%97%B0%EC%82%B0%EC%9E%90-1
https://catch-me-java.tistory.com/31
'자바(Java)' 카테고리의 다른 글
[자바] HashSet 중복값 처리 과정, 배열로 변경하는 법 (0) | 2023.08.08 |
---|---|
[자바] 자바 조건문과 반복문, JUnit 5 (0) | 2023.08.05 |
[자바] 자바의 프리미티브 타입, 변수, 배열 선언 (0) | 2023.07.24 |
[자바] JVM, 자바 실행방법 (2) | 2023.07.16 |
[Java] 자바 StringBuilder 사용법 (0) | 2023.03.19 |