경주장

3주차 과제. 연산자(~1/27) 본문

JAVA/whiteship_live-study

3주차 과제. 연산자(~1/27)

달리는치타 2022. 1. 24. 22:02

목표

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

 

학습할 것

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

switch case문의 switch와는 다른 Java 13에 새롭게 추가된 switch 연산자입니다. 잘 활용되지 않는것 같아 스킵하겠습니다.


연산자와 연산식

프로그램에서 데이터를 처리하여 결과를 산출하는 것을 연산(operations)이라고 한다.

연산에 사용되는 표시나 기호를 연산자(operator), 연산되는 데이터는 피연산자(opreand)라고 한다.

연산자와 피연산자를 이용하여 연산의 과정을 기술한 것을 연산식(expressions)라고 한다.

x+y
x-y
x*y+z
x==y

자바의 다양한 연산자

연산자 종류 연산자 피연산자 수 산출값  
산술 +,-,*,/,% 이항 숫자 사칙연산 및 나머지 계산
부호 +,- 단항 숫자 부호 변환
문자열 + 이항 문자열 Concatenation
대입 =,+=,-=,*=,/=,%=, &=,^=!=<<=,>>=,>>>= 이항 다양하다 우변의 값을 좌변의 변수에 대입
증감 ++,-- 단항 숫자 1만큼 증가, 감소
비교 ==, !=, >,<, >=, <=,
instanceof(?)
이항 boolean 값의 비교
논리 !, &&, || 단항, 이항 boolean 논리적 NOT, AND, OR
조건 (조건식)?A:B 삼항 다양하다 (조건식)이 true이면 A, false이면 B
비트 ~,&,|,^ 이항 숫자,boolean 비트 NOT,AND,OR,XOR 연산
시프트 >>,<<,>>> 이항 숫자 left shift (<<)
arithmetic right shift(>>)
unsigned right shift(>>>)

익숙하지 않은 연산자인 instanceof에 대해서만 실습을 해보았습니다.

 

instanceof 연산자의 문법은 다음과 같습니다.

 

인스턴스이름 instanceof 클래스또는인터페이스이름

왼쪽 피연산자(인스턴스)가 오른쪽 피연ㅅ나자인 클래스 또는 인터페이스로부터 생성되었다면 true 그렇지 않다면 false를 반환한다.

형변환 가능 여부를 확인한다.

* 형변환이 불가능한 즉 타입이 상위클래스도 하위클래스도 아닐경우에는 에러가 난다.

 

class A{}
class B extends A{}

interface C{}
class D implements C{};

public class Main {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();

        System.out.println(a instanceof A); // true
        System.out.println(b instanceof A); // true
        System.out.println(a instanceof B); // false
        System.out.println(b instanceof B); // true
        
        D d = new D();

//        System.out.println(d instanceof A);
//        -> java: incompatible types: D cannot be converted to A
//        System.out.println(d instanceof B);   
//        -> java: incompatible types: D cannot be converted to B
        System.out.println(d instanceof C);
        System.out.println(d instanceof D);
    }
}

 


화살표(->) 연산자

 

lambda 문법 - 자바 8에서 도입되었으며 익명 클래스 대신 사용하여 코드를 보다 간결하고 읽기 쉽게 만들 수 있습니다.

 

List<Integer> list = new ArrayList<>();

위와 같은 ArrayList를 Collections.sort 함수를 사용해 절댓값이 큰 순서대로 정렬하는 코드를 작성해 보겠습니다.

public static <T> void sort(List<T> list, Comparator<? super T> c)

 Collections.sort 는 첫번째 인자로 list를 두번째 인자로 T혹은 T의 부모타입의 Comparator<? super T> C를 받습니다. 

 

Comparator를 넘겨주기 위해서 Java 8이전의 문법에서는

Collections.sort 함수 내부적으로 사용하는 Comparator의 매서드인 compare를 override한 Comparator를 구현한 (익명)클래스를 작성해야 했습니다.

 

Collections.sort(list,
        new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return abs(o2) - abs(o1);
            }
        });

 

람다 문법의 도입으로 위와 같은 익명클래스의 작성은 아래와 같이 줄여 질 수 있습니다. 

 

Collections.sort(list,
        (Integer o1, Integer o2) -> {
            return abs(o2) - abs(o1);
        });

 

더 나아가서 파라미터의 타입(타입 추론으로 가능)과 return 까지 줄여버릴 수 있습니다.

Collections.sort(list, (o1, o2) -> abs(o2) - abs(o1));

익명클래스의 무자비한 라인 숫자가 단 한줄로 줄어들었습니다.

 


해당 문법이 적용가능한 클래스인 Comparator를 살펴보면 @FunctionalInterface라는 어노테이션이 붙어 있습니다.

 

함수형 인터페이스란 1 개의 추상 메소드를 갖는 인터페이스를 말합니다.
Java8 부터 인터페이스는 기본 구현체를 포함한 디폴트 메서드 (default method) 를 포함할 수 있습니다.
여러 개의 디폴트 메서드가 있더라도 추상 메서드가 오직 하나면 함수형 인터페이스입니다.
자바의 람다 표현식은 함수형 인터페이스로만 사용 가능합니다.

Comparator를 살펴보면 추상메서드 

int compare(T o1, T o2);

와 수많은 default, static 매서드로 구현 되어 있습니다.

 

화살표 연산자는 자바 8에 함께 도입된 stream과 조합되어 강력한 기능과 가독성을 제공합니다.


연산자 우선 순위

연산자 우선순위 도표

괄호를 통해 복잡한 연산자 우선순위를 덜 신경 써도 되도록 코드를 작성하자!

코딩을 하면서 손과 눈에 익은 연산자 우선순위이지만 그럼에도 눈길이 가는 부분은 역시 괄호가 1 순위라는 점이다. 

또한 if, while의 조건문안에 작성을 하며 가장 많이 신경쓰게 되는 &&가 ||보다 앞선다는 점도 눈길이 간다.