개발/Java

[live-study] 3: 연산자

Soongjamm 2020. 12. 26. 16:58

백기선님이 진행하시는 live-study 3주차 과제
3주차 과제

목표

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

학습할 것

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

산술 연산자

<용어>
연산자: 어떠한 기능을 수행하는 기호
피연산자: 연산자의 작업 대상

<연산자>

  • + : 덧셈 기능을 수행한다.

    • 숫자와 String 모두에 적용 가능하다.

      • "abc" + "cde"; // abccde
         10 + 20; // 30
    • char의 경우 유니코드와 숫자를 혼합한 결과를 char변수에 대입할 수 없고, 결과 타입을 일치시켜야 한다.

      • char a = 'a';
        // char ch = a + 1; // 불가능.
        char ch = (char)(a+1); // OK
    • 증가연산자 ++x = x + 1과 같은 일을 수행한다.

  • - : 뺄셈 기능을 수행한다.

    • 감소연산자 --x = x - 1과 같은 일을 수행한다.
  • * : 곱셈 기능을 수행한다.

  • / : 나눗셈 기능을 수행한다.

  • % : 나머지(modular)기능을 수행한다.

    • int modular = 5%3; // 5 나누기 3의 나머지인 2가 저장된다.
      double modular2 = 8.0 % 2.5; // 0.5가 저장된다.

산술 연산자는 이항연산자이고, 피연산자중 표현범위가 큰 타입으로 프로모션하여 타입을 일치시킨다.
ex. char + int => int + int => int

특이한 점은 다음 예제이다.

byte a = 1;
byte b = 2;
// byte result = a + b; // int + int가 되어 에러. 캐스팅 필요
byte result = (int)(a+b); // 성공

위처럼 되는 이유는 byte에서 수행되는 수학적 결과는 int형으로 저장되기 때문이다.
byte result = a + bbyte result = (int)a + (int)b; 와 같다는 말이다.

비트 연산자

피연산자를 비트단위로 계산한다. 실수형(float, double)을 제외한 모든 기본형에 사용할 수 있다.

  • | (OR 연산자): 피연산자중 어느 한쪽이 1이면 1이다.

    • 0|0 => 0  
      0|1 => 1
      1|1 => 1
  • & (AND 연산자): 피연산자 양쪽이 1이여야 1이다.

    • 0|0 => 0  
        0|1 => 0
        1|1 => 1
  • ^ (XOR 연산자): 피연산자가 서로 다를때 1이다.

    • 0|0 => 0  
      0|1 => 1
      1|1 => 0

10진수로 예를 들면 1 ^ 3은 다음과 같다.
0000 0001 (= 1) ^
0000 0011 (= 3)
결과는 0000 0010 = 2가 된다.

관계 연산자

값을 비교할때 사용하는 연산자이다.
피연산자를 같은 타입으로 두고 계산한다.
결과값으로 boolean truefalse를 반환한다.
참조형은 ==!=만 사용할 수 있다.

  • x==y : x와 y가 같으면 true, 다르면 false
  • x!=y : x와 y가 다르면 true, 같으면 false
  • x>y : x가 y보다 크면 true, 같거나 작으면 false
  • x>=y : x가 y보다 크거나 같으면 true, 작으면 false
  • x<y : x가 y보다 작으면 true, 같거나 크면 false
  • x<=y : x가 y보다 작거나 같으면 true, 크면 false

'0'0은 각각 char(유니코드 48)와 int다. 그러므로 '0' == 0false 이다.

논리 연산자

피연산자가 반드시 boolean이여야 하고, 논리 연산의 결과 또한 boolean이다.

  • x&&y : x와 y가 모두 true일 때 true, 하나라도 false라면 false를 반환
  • x||y : x와 y중 하나만 true여도 true, 둘 다 false라면 false를 반환

&&가 ||보다 우선순위가 높다. &&와 ||를 같이 사용하는 경우 괄호를 사용하도록 한다.

 (1==0) || (1==1) // true  
 (1==0) && (1==1) // false  
 ('0'!=0) || (1==1) // true
 ('0'!=0) && (1==1) // true
 ('0'==0) && (1==1) // false

instanceof

instanceof는 참조변수가 어떠한 타입이 맞는지 여부를 확인하기 위해 사용한다.
참조변수 instanceof 클래스(타입) 으로 사용할 수 있고, true면 참조변수를 해당 클래스로 형변환 할 수 있다는 의미이다.

다음의 상속관계인 서브클래스 인스턴스도 슈퍼클래스를 참조하고 있기 때문에 true가 나온다.

public class SuperClass {

}

public class SubClass extends SuperClass {

}

public class Main {
    public void main() {
        SuperClass subClass = new SubClass();
        subClass instanceof SuperClass; // true
    }
}

assignment(=) operator

좌측 피연산자에 오른쪽 피연산자를 대입하는 것을 말한다.
좌측 피연산자는 상수가 아니여야 한다.

=앞에 다른 연산자가 오면 좌측 피연산자에 우측 피연산자를 연산하고, 다시 좌측 피연산자에 저장한다 는 의미가 된다. (프리미티브 타입에만 적용, 단 +=은 String에도 적용 가능 )

int a = 10 // a에 10을 대입한다.
a += 10 // a = a + 10과 같은 의미다. 즉 현재 a == 20
a -= 5 // a = a - 5. --> a == 15
a *= 2 // a = a * 2 --> a == 30
a /= 3 // a = a / 3 --> a == 10
a %= 9 // a = a % 9 --> a == 1
// 시프트 연산자도 사용할 수 있다.
int a = 1 // 2진수로 0000 0001
a <<= 4 // 4만큼 왼쪽으로 비트를 이동한다. 0001 0000 == 10진수 16
a >>= 1 // 1만큼 오른쪽으로 비트를 이동한다. 0000 1000 == 10진수 8

화살표(->)

자바 8부터 도입된 람다식에 이용되는 연산자로, 간단하게 설명하면 재사용되지 않는 함수나 인터페이스를 익명함수로 구현하는데, 익명함수 작성을 간편하게 해주는 것이 람다식이다.

매개변수 -> 리턴 값 or () -> 리턴 값 or 매개변수 -> {//코드} or () -> {//코드} 의 모습을 하고있다.

람다식 사용 전

public interface PlusInterface {
    int plus(int a, b);
}

public class PlusImplement implements PlusInterface {
    @Override
    int apply(int a, int b){
        return a + b;
    }
}

public class Main {
    public void main() {
        PlusInterface plus = new PlusImplement();
        plus.apply(10, 20);
    }

}

`람다식 사용 후` ``` public interface Plus { void plus(int a, int b); }

public class Main {
public void main() {
PlusInterface plus = (a, b) -> a+b;
}
}


## 3항 연산자
조건식을 한 줄에 나타낼 수 있는 연산 방법이다.  
`조건 ? A : B`의 형태로 나타낸다. 만약 조건이 true일 경우 A, false일 경우 B를 반환한다.
// 만약 나이가 성인나이보다 어리냐는 조건에 true이면 "학생", false이면 "성인"이라는 문자열을 person에 저장한다.  
int myAge = 15;  
int adultAge = 20;  
String person = myage < adultAge ? "학생" : "성인";

연산자 우선순위

출처 : 자바의 정석 베이직https://github.com/castello/javajungsuk_basic/blob/master/javajungsuk_basic_%EC%9A%94%EC%95%BD%EC%A7%91.pdf

  • ()괄호 > {}괄호 > 산술 > 비교 > 논리 > 대입 순이다.
  • 단항 > 이항 > 삼항 순이다.
  • 연산 진행방향은 단항, 대입 대입연산자를 제외하고 왼쪽 -> 오른쪽 순이다.
  • 증감연산자는(++, --) 피연산자 앞에 올경우 해당 줄의 코드를 실행하기 전에 연산을 하고, 뒤에 올 경우 코드를 실행한 후 연산한다.
    • int a = 1;
      int b = 0;
      b = a++; // b = 1 (변하기전 a의 값) -> 마지막에 a = a + 1

Java 13. switch 연산자

자바 12에서 switch문을 statement가 아닌 ->를 사용한 expression으로 사용할 수 있게 되었는데, 자바 13에서 switch expression의 break대신 yield 키워드를 사용해서 반환되야 하는 값을 지정한다. (이 부분은 완전하게 이해가 되지 않았다)

// 오라클에 나와있는 예제
// https://docs.oracle.com/en/java/javase/13/language/switch-expressions.html
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);

참고

https://github.com/castello/javajungsuk_basic/blob/master/javajungsuk_basic_%EC%9A%94%EC%95%BD%EC%A7%91.pdf
https://kils-log-of-develop.tistory.com/336
https://stackoverflow.com/questions/58049131/what-does-the-new-keyword-yield-mean-in-java-13