일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 합병 정렬
- 접근지시자
- 상속
- System.in
- 스파르타코딩클럽
- github api
- auto.create.topics.enable
- 자바스터디
- 자바할래
- throwable
- yield
- 제네릭 타입
- Switch Expressions
- 로컬 클래스
- annotation processor
- 함수형 인터페이스
- raw 타입
- System.err
- junit 5
- 항해99
- docker
- 정렬
- 제네릭 와일드 카드
- System.out
- 바운디드 타입
- 프리미티브 타입
- Study Halle
- 람다식
- 브릿지 메소드
- 익명 클래스
Archives
- Today
- Total
코딩하는 털보
STUDY HALLE - 3주차 본문
STUDY HALLE
3주차 : 연산자
목표
자바가 제공하는 다양한 연산자를 학습하세요.
학습할 것
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- switch 연산자
산술연산자
수학적인 계산에 사용되는 연산자이다.
연산자 | 의미 |
---|---|
+ | 더하기 |
- | 빼기 |
* | 곱하기 |
/ | 나누기 |
% | 나머지 값 구하기 |
public class Test {
public static void main(String args[]) {
int a = 7;
int b = 3;
System.out.println(a+b); // 7+3=10
System.out.println(a-b); // 7-3=4
System.out.println(a*b); // 7*3=21
System.out.println(a/b); // 7/3 값 2
System.out.println(a%b); // 7/3 나머지 1
//계산되는 순서는 수학의 사칙연산과 동일하다.
System.out.println(a+b*30); // 7+3*30=97
}
}
'+' 연산자는 문자열과 문자열을 결합할 때도 사용된다.
public class Test {
public static void main(String args[]) {
int a = "안녕";
int b = "하세요";
System.out.println(a+b); // "안녕하세요"
}
}
비트연산자
연산자 | 의미 |
---|---|
~ | 비트 반전 (1의 보수) |
& | 비트 단위의 AND, 1&1인 경우에 1, 나머지 0 |
^ | 비트 단위의 XOR, 두 비트가 서로 다른경우 1 |
<< | 왼쪽 shift, 0으로 채우기 |
>> | 오른쪽 shift, 부호 비트로 채우기 |
>>> | 오른쪽 shift, 0으로 채우기 |
비트 연산자의 사용처
- 비트켜기 : &00001111, 하위 4bit중 1인 비트만 꺼내기
- 비트끄기 : |11110000, 하위 4bit중 0인 비트만 0으로 만들기
- 비트토글 : 모든 비트들을 0은 1로, 1은 0으로 바꾸고 싶을 때
- shift를 통해 곱셈 나눗셈을 빠르게할 수 있다.
public class Test {
public static void main(String args[]) {
int num1 = 0B00001010; //10
int num2 = 0B00000101; //5
System.out.println(~num1); //11110101 -11
System.out.println(num1 & num2); //00000000 0
System.out.println(num1 | num2); //00001111 15
System.out.println(num1 ^ num2); //00001111 15
System.out.println(num2 << 1); //(x2) 00001010 10
System.out.println(num2 << 2); //(x2^2) 00010100 20
System.out.println(num2 << 3); //(x2^3) 00010100 40
System.out.println(num2 >> 2); //(/2^2) 00000001 1
System.out.println(num2 & 0B00001111); //00000101 5
System.out.println(num2 | 0B11110000); //11110101 245
}
}
관계연산자
두 개의 변수나 리터럴을 서로 비교할 때 사용한다.
비교 연산자라고도 한다.
결과가 true/false로 반환 된다.
연산자 | 의미 |
---|---|
A > B | A가 B보다 크면 true, 아니면 false |
A < B | A가 B보다 작으면 true, 아니면 false |
A >= B | A가 B보다 크거나 같으면 true, 아니면 false |
A <= B | A가 B보다 작거나 같으면 true, 아니면 false |
A == B | A와 B가 같으면 true, 아니면 false |
A != B | A와 B가 다르면 true, 아니면 false |
논리연산자
두개의 피연산자의 결과를 비교할 때 사용한다.
- 결과가 true/false로 반환 된다.
연산자 | 의미 |
---|---|
&& | 논리 곱, 두 항 모두 참이어야 true, 아니면 false |
! | 부정, 항의 논리 결과 변경 (true -> false, false -> true) |
public class Test {
public static void main(String args[]) {
int a = 10;
int b = 20;
System.out.println("a>b = "+(a>b)); //a>b = false
System.out.println("a<b = "+(a<b)); //a<b = true
System.out.println("a==b = "+(a==b)); //a==b = false
System.out.println("a!=b = "+(a!=b)); //a!=b = true
boolean value = a<b&&a!=b;
System.out.println(value); //true&&true = true
value = a<b&&a==b;
System.out.println(value); //true&&false = false
value = a<b||a==b;
System.out.println(value); //true||false = true
value = a>b||a==b;
System.out.println(value); //false||false = false
System.out.println(!value); //!false = true
}
}
논리 연산자는 단락 회로 평가 방식으로 실행된다.
단락 회로 평가
앞 항 결과만으로 논리 연산자 결과가 나온다면 뒷 항은 평가되지 않음.
프로그램에서 예상하지 못한 결과가 발생할 수 있으므로 유의가 필요하다.
public class Test {
public static void main(String[] args) {
int num = 10;
int i = 2;
boolean value = ((num=num+10)<10)&&((i=i+2)<10);
//앞 항의 결과가 false이므로 value가 결정되어 num은 변경되지만 i는 변경되지 않는다.
System.out.println(value); //false
System.out.println(num); //20
System.out.println(i); //2
}
}
instanceof
instanceof 연산자는 피연산자의 타입을 비교하는 특별한 연산자이다.
variable instanceof type;
- 왼쪽 피연산자로 변수를 받는데, 참조 변수만 받을 수 있다.
- 오른쪽 피연산자로 타입을 받는데, 레퍼런스 타입만 받을 수 있다.
- 값의 결과로 참조 변수가 해당 타입이거나 그 타입으로 형 변환 할 수 있다면 true, 아니면 false를 반환한다.
public class Test {
public static void main(String args[]) {
String a = "yeah";
System.out.println(a instanceof String); //true
}
}
주로 조건문에서 업케스팅된 객체가 원래 어떤 타입이었는지를 확인하기 위해 사용된다.
public class Test {
public static void main(String[] args) {
Sedan sedan = new Sedan();
Car car = (Car)sedan; //car는 sedan이 Car로 업캐스팅된 인스턴스.
if (car instanceof Sedan) { //car는 원래 sedan이었으므로 Sedan으로 형 변환 할 수 있다.
Sedan new_sedan = (Sedan)car;
System.out.println("This car is Sedan.");
} else {
System.out.println("This car is not Sedan.");
}
}
}
class Car {
String color;
int door;
}
class Sedan extends Car {
}
assignment(=) operator
대입 연산자('=') : 변수에 리터럴이나 인스턴스 또는 다른 변수의 값을 대입할 때 사용한다.
int age = 10;
복합 대입 연산자 : 대입 연산자 앞의 연산자의 결과를 변수에 대입할 때 사용한다.
연산자 | 의미 |
---|---|
a += b | a에 b를 더한 뒤 결과를 다시 a에 대입 |
a -= b | a에서 b를 뺀 뒤 결과를 다시 a에 대입 |
a *= b | a와 b를 곱한 뒤 결과를 다시 a에 대입 |
a /= b | a를 b로 나눈 값을 다시 a에 대입 |
a %= b | a를 b로 나눈 나머지를 다시 a에 대입 |
public class Test {
public static void main(String[] args) {
int a = 10;
a += 10;
System.out.println(a); //10+10 = 20
a -= 10;
System.out.println(a); //20-10 = 10
a *= 10;
System.out.println(a); //10*10 = 100
a /= 10;
System.out.println(a); //100/10 의 값 10
a %= 3;
System.out.println(a); //10/3의 나머지 1
}
}
화살표(->) 연산자
람다식 : 자바 8부터 사용가능한 식별자 없이 실행 가능한 함수 표현식이다.
- 함수를 보다 간결하게 표현할 수 있다.
- 함수가 이름을 가질 필요가 없다.
- 클래스를 생성하지 않고 함수의 호출만으로 기능 수행 (내부적으로 익명 객체 사용)
- 매개변수의 타입 추론을 사용할 수 있다.
- 무명 함수는 재사용이 불가능하고 디버깅이 어렵다.
(매개변수) -> {실행문}
InterFace itfc = str -> {System.out.println(str);};
InterFace2 itfc2 = (x,y) -> x+y //구현부가 return 문 하나라면 return, 중괄호 생략 가능
interface StringConcat{
void makeString(String str1, String str2);
}
public class TestStringConcat {
public static void main(String[] args) {
StringConcat concat = (s,v) -> System.out.println(s+" "+v); //함수형 프로그래밍, 람다식 사용
concat.makeString("hello","world"); //클래스 구현이 필요없고, 메서드 구현을 따로 만들 필요도 없음.
//실제로는 아래처럼 익명 내부클래스로 동작한다.
StringConcat concat2 = new StringConcat() {
@Override
public void makeString(String str1, String str2) {
System.out.println(str1+" "+str2);
}
};
concat2.makeString("hello","world");
}
}
람다식은 프로그램내에서 변수처럼 사용할 수도 있다.
interface PrintString{
void showString(String str);
}
public class TestLambda {
public static void main(String[] args) {
PrintString lambdaStr = str -> System.out.println(str); //함수의 구현부가 변수로 대입
lambdaStr.showString("Test1");
showMyString(lambdaStr); //매개변수로 활용
PrintString lambdaStr2 = returnString(); //반환된 구현부를 변수에 대입
lambdaStr2.showString("Test3");
}
public static void showMyString(PrintString p) {
p.showString("Test2");
}
public static PrintString returnString() {
return str->System.out.println(str+"!!!"); //함수의 구현부를 반환
}
}
3항 연산자
IF문 대신 사용할 수 있는 연산자.
- 동일한 IF,ELSE 코드보다 라인수가 줄어든다.
(조건문) ? val1 : val2;
//조건문이 참일 경우 val1을 반환하고 거짓인 경우 val2를 반환한다.
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 30;
//더 큰 값을 변수에 대입.
int bigger = (a>b) ? a : b;
System.out.println(bigger); //더 큰 값인 30이 출력된다.
}
}
연산자 우선 순위(Operator Precedence)
연산자가 여러개 있을 때 먼저 실행되는 우선순위가 있다.
- 괄호의 우선순위가 제일 높고, 산술 > 비교 > 논리 > 대입의 순서.
- 단항 > 이항 > 삼항의 순서.
- 연산자의 연산 진행방향은 왼쪽에서 오른쪽으로 수행되며, 단항 연산자와 대입 연산자의 경우에는 오른쪽에서 왼쪽으로 수행된다.
Priority | Operator | Direction |
---|---|---|
1 | [] . () |
왼쪽에서 오른쪽 |
2 | a++ a-- |
방향 없음 |
3 | ++a --a +,- ! ~ : 단항 연산자 |
오른쪽에서 왼쪽 |
4 | () new |
오른쪽에서 왼쪽 |
5 | * / % |
왼쪽에서 오른쪽 |
6 | + - +(문자 결합) |
왼쪽에서 오른쪽 |
7 | << >> >>> |
왼쪽에서 오른쪽 |
8 | < <= > >= instanceof |
방향 없음 |
9 | == != |
왼쪽에서 오른쪽 |
10 | & |
왼쪽에서 오른쪽 |
11 | ^ |
왼쪽에서 오른쪽 |
12 | ||
13 | && |
왼쪽에서 오른쪽 |
14 | ||
15 | ?: |
오른쪽에서 왼쪽 |
16 | = += -= *= /= %= &= ^= |
= <<= >>= >>>= |
Switch Expressions
자바 12부터 switch 문을 강화한 Switch Expressions이 등장하였다.
- Switch Expressions
- case 병합을 ','(콤마)로 할 수 있다.
- break으로 값을 반환할 수 있다. (Java 13부터 yield로 대체되었다. )
- label rules(화살표)로 값을 반환할 수 있다.
- 현재 preview feature이며, 기본적으로는 disabled이고 사용하려면 추가 설정이 필요하다.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int month = scanner.nextInt();
int day = switch(month) {
//case 1: case 5: case 7: case 8: case 10: case 12:
//case 병합을 나열하는 것도 간편하게 바뀌었다.
case 1, 5, 7, 8, 10, 12:
yield 13; //break 대신 yield를 사용하며, 결과를 반환한다.
case 2:
yield 28;
case 3, 4, 6, 9, 11:
yield 30;
default :
System.out.println("Error");
yield 0;
}
System.out.println(month + "월의 날짜 수는 " + day + "일 입니다.");
}
}
label rules(화살표)를 사용한 예시
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int month = scanner.nextInt();
int day = switch(month) {
case 1, 5, 7, 8, 10, 12 -> 13;
case 2 -> 28;
case 3, 4, 6, 9, 11 -> 30;
default -> {
System.out.println("Error");
yield 0;
}
}
System.out.println(month + "월의 날짜 수는 " + day + "일 입니다.");
}
}
preview feature 를 위한 컴파일 및 실행
javac --enable-preview --release 12 Example.java
java --enable-preview Example
Comments