<Java> 연산자

라모스·2021년 8월 23일
0

Java☕

목록 보기
3/14
post-thumbnail

" 자바가 제공하는 다양한 연산자를 학습하세요. "

학습할 것

  • 산술 연산자
  • 비트 연산자
  • 관계 연산자
  • 논리 연산자
  • instanceof
  • assignment(=) operator
  • 화살표(->) 연산자
  • 3항 연산자
  • 연산자 우선 순위
  • (optional) Java 13. switch 연산자

1. 산술 연산자

수학적 계산에 사용되는 연산자. 두 개의 피연산자를 가지는 이항 연산자.

산술 연산자설명
+더하기
-빼기
*곱하기
/나누기
%나머지
public class ArithmeticOperator {
    public static void main(String[] args) {
        int result = 1 + 2;
        System.out.println("1 + 2 = " + result);  // 결과: 3
        int original_result = result;

        result = result - 1;
        System.out.println(original_result + " - 1 = " + result);  // 결과: 2
        original_result = result;

        result = result * 2;
        System.out.println(original_result + " * 2 = " + result);  // 결과: 4
        original_result = result;

        result = result / 2;
        System.out.println(original_result + " / 2 = " + result);  // 결과: 2
        original_result = result;

        result = result + 8;
        System.out.println(original_result + " + 8 = " + result);  // 결과: 10
        original_result = result;

        result = result % 7;
        System.out.println(original_result + " % 7 = " + result);  // 결과: 3
        original_result = result;
    }
}

2. 단항 연산자

단항 연산자설명
+양수
-음수
++1 증가
--1 감소
!반대(논리 연산자)
public class UnaryOperator {
    public static void main(String[] args) {
        int result = +1;
        System.out.println(result); // 결과: 1

        result--;
        System.out.println(result); // 결과: 0

        result++;
        System.out.println(result); // 결과: 1

        result = -result;
        System.out.println(result); // 결과: -1

        boolean success = false;
        System.out.println(success); // false
        System.out.println(!success); // true
    }
}

3. 비트 연산자

비트(bit) 단위로 논리 연산을 할 때 사용하는 연산자

비트 연산자설명
&대응되는 비트가 모두 1이면 1을 반환(비트 AND 연산)
|대응되는 비트 중에서 하나라도 1이면 1을 반환(비트 OR 연산)
^대응되는 비트가 서로 다르면 1을 반환(비트 XOR 연산)
~비트를 1이면 0, 0이면 1로 반전(비트 NOT 연산, 1의 보수)
<<명시된 수만큼 비트들을 모두 왼쪽으로 이동(left shift 연산)
>>부호를 유지하고 지정된 수만큼 모두 오른쪽으로 이동(right shift 연산)
>>>명시된 수만큼 비트들을 모두 오른쪽으로 이동, 새로운 비트는 0으로 채움(unsigned right shift 연산)
// 비트 NOT 연산(보수 연산)
byte b = ~12; // ~00001100
System.out.println(b); // 결과: -13
System.out.println(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
// 결과: 00000100

byte flags = 12; // 00001100
byte f = 8;      // 00001000
flags = (byte) (flags & ~f); // 00001100 & ~00001000
System.out.println(String.format("%8s", Integer.toBinaryString(flags & 0xFF)).repalce(' ', '0'));
// 00000100

// 비트 AND 연산
10 & 7                  // 00001010 & 00000111 → 00000010
if((flags & f) != 0)    // 플래그 값들 중에서 특정 플래그 값 f가 의도대로 세팅되어 있는지 확인.

// 비트 OR 연산
10 | 7                  // 00001010 | 00000111 → 00001111
flags = flags | f;      // 플래그 값들 중에서 특정 플래그 값 f를 세팅(f 플래그값 위치에 1이 있음)

// 비트 XOR 연산
10 ^ 7                  // 00001010 ^ 00000111 → 00001101

// left shift(<<)
10 << 1                 // 0b00001010 << 1 = 00010100 = 20 = 10*2
7 << 3                  // 0b00000111 << 3 = 00111000 = 56 = 7*8
-1 << 2                 // 0xFFFFFFFF << 2 = 0xFFFFFC = -4 = -1*4

// right shift(>>)
10 >> 1                 // 00001010 >> 1 = 00000101 = 5 = 10/2
27 >> 3                 // 00011011 >> 3 = 00000011 = 3 = 27/8
-50 >> 2                // 11001110 >> 2 = 11110011 = -13 != -50/4

// unsigned right shift(>>>)
0xff >>> 4              // 11111111 >>> 4 = 00001111 = 15 = 255/16
-50 >>> 2               // 0xFFFFFFCE >>> 2 = 0x3FFFFFF3 = 1073741811

4. 관계 연산자

두 피연산자의 상대적인 크기를 판단하는 연산자. 왼쪽의 피연산자와 오른쪽의 피연산자를 비교하여, 어느 쪽이 더 큰지, 작은지, 또는 서로 같은지를 판단. 결합방향은 왼쪽에서 오른쪽

관계 연산자설명
==같으면 true
!=다르면 true
>왼쪽이 크면 true
>=왼쪽이 오른쪽보다 크거나 같으면 true
<오른쪽이 크면 true
<=오른쪽이 왼쪽보다 크거나 같으면 true
char c1 = 'a', ch2 = 'A';
System.out.println(ch1 == ch2); // false
System.out.println(ch1 > ch2); // true

5. 논리 연산자

논리적으로 true와 false를 판단

논리 연산자설명
&&논리식이 모두 참이면 true(논리 AND 연산)
||논리식 중에 하나라도 참이면 true(논리 OR 연산)
!논리식이 true이면 false, false이면 true(논리 NOT 연산)
^논리식이 서로 다를 때 true(논리 XOR 연산)
public class LogicalOperator {
    public static void main(String[] args) {
        System.out.println('a' > 'b');    // false
        System.out.println(3 >= 2);       // true
        System.out.println(-1 < 0);       // true
        System.out.println(3.45 <= 2);    // false
        System.out.println(3 == 2);       // false
        System.out.println(3 != 2);       // true
        System.out.println(!(3 != 2));    // false

        System.out.println((3 > 2) && (3 > 4)); // false
        System.out.println((3 != 2) || (-1 > 0)); // true
        System.out.println((3 != 2) ^ (-1 > 0));  // true
    }
}

6. instanceof

참조 변수가 참조하고 있는 인스턴스의 실제 타입을 반환.
해당 객체가 어떤 클래스(부모 클래스 포함)나 인터페이스로부터 생성되었는지 판별

public class InstanceofEx {
    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 {}

// 결과
obj1 instanceof Parent: true
obj1 instanceof Child: false
obj1 instanceof MyInterface: false
obj2 instanceof Parent: true
obj2 instanceof Child: true
obj2 instanceof MyInterface: true

7. assignment(=) operator

  • 오른쪽의 값을 왼쪽 피연산자에 할당
int a = 0;
int b = 0;
int c = 1;
  • 객체 참조를 할당
Player Ronaldo = new Player("Cristiano Ronaldo", "Portugal", "JuventusFC", "FW", "187", "83.5", "19850205");
Player Messi = new Player("Lionel Messi", "Argentina", "FCBarcelona", "FW", "170", "72", "19870624");
  • 'a = b = c'의 경우, 오른쪽에서 왼쪽으로 수행(a = (b = c))
  • 5개의 산술 연산자, 6개의 비트 및 시프트 연산자와 결합해서 사용 가능
i += 2;  // i를 2 증가해서 저장
c -= 5;  // c를 5 감소해서 저장
flags |= f; // 플래그 값들 중에서 특정 플래그 값 f를 세팅해서(비트 OR 연산) flags 저장
flags &= ~f; // 플래그 값들 중에서 특정 플래그 값 f를 세팅하지 않도록(f의 보수로 비트 AND 연산) flags 저장

8. 화살표(->) 연산자

  • Java 8 이상의 람다식에서 익명 함수를 만들 때 사용
  • 코드가 간결해지는 장점이 있음
  • 화살표 왼쪽에 인자, 오른쪽에 실제 표현식을 쓴다.
// (인자, ...) -> { /* 메소드 바디 */ }

// 두 개의 숫자 더하기
public interface Compare {
    public int compareTo(int a, int b);
}
public static void exec(Compare compare) {
    int k = 10;
    int m = 20;
    int value = compare.compareTo(k, m);
    System.out.println(value);
}
public static void main(String[] args) {
    exec((i, j) -> { // compareTo(int a, int b) 부분, Compare 인터페이스를 구현
        return i + j;
    });
}

// 두 개의 숫자 중 큰 수 출력하기
@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));
}

// Runnable 인스턴스 생성
Runnable runnable = ()->{
    for(int i = 0; i < 30; i++) {
        System.out.println(i);
    }
};
Thread thread = new Thread(runnable);
thread.start();

// Thread 생성
Thread thread = new Thread(()-> {
    for(int i = 0; i < 10; i++) {
        System.out.println(i);
    }
});
thread.start();

9. 3항 연산자

  • if~else 구문을 간결하게 만든 표현식
  • 3개의 피연산자가 물음표와 콜론으로 나눠져 있는 형태로 표현한다.
// <조건> ? <true일 경우 반환되는 값> : <false일 경우 반환되는 값>
x > y ? x : y

// 두 번째와 세 번째 연산자는 같은 타입으로 변환할 수 있어야 함.
int completedChapter = 3;
System.out.println((completedChapter >= 14) ? "티셔츠" : "공부해");

10. 연산자 우선 순위


// 출처: 명품 Java Programming

11. Java 13, switch 연산자

아래와 같은 switch 문이 있을 때,

public enum Day { SUNDAY, MONDAY, TUESDAY,
    WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; }

// ...

    int numLetters = 0;
    Day day = Day.WEDNESDAY;
    switch (day) {
        case MONDAY:
        case FRIDAY:
        case SUNDAY:
            numLetters = 6;
            break;
        case TUESDAY:
            numLetters = 7;
            break;
        case THURSDAY:
        case SATURDAY:
            numLetters = 8;
            break;
        case WEDNESDAY:
            numLetters = 9;
            break;
        default:
            throw new IllegalStateException("Invalid day: " + day);
    }
    System.out.println(numLetters);

Java 12부터는 콜론(:)대신 화살표 연산자(->)를 사용할 수 있다.

int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> numLetters = 6;
    case TUESDAY                -> numLetters = 7;
    case THURSDAY, SATURDAY     -> numLetters = 8;
    case WEDNESDAY              -> numLetters = 9;
    default -> throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);

Java 13부터는 break 대신 yield를 사용한다.

Day day = Day.WEDNESDAY;
int numLetters = switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        yield 6;
    case TUESDAY:
        System.out.println(7);
        yield 7;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        yield 8;
    case WEDNESDAY:
        System.out.println(9);
        yield 9;
    default:
        throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);

위에서는 콜론이 있는 구문에서 yield가 빠지면, 런타임 에러가 발생한다. 하지만 아래와 같이 화살표 연산자를 사용할 경우에는 yield가 빠지면, 컴파일 에러가 발생하여 미리 알 수 있기 때문에 화살표 연산자를 사용할 것을 권장한다.

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> {
        System.out.println(6);
        yield 6;
    }
    case TUESDAY -> {
        System.out.println(7);
        yield 7;
    }
    case THURSDAY, SATURDAY -> {
        System.out.println(8);
        yield 8;
    }
    case WEDNESDAY -> {
        System.out.println(9);
        yield 9;
    }
    default -> {
        throw new IllegalStateException("Invalid day: " + day);
    }
};

References

profile
Step by step goes a long way.

0개의 댓글