일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 백준
- 코딩봉사
- kotlin
- 알고리즘
- 시나공
- 회고
- MYSQL
- 자바
- 공부일지
- 문제풀이
- 코틀린
- java
- 프로그래머스
- 1과목
- programmers
- 파이썬
- 백준 알고리즘
- 정보처리산업기사
- SW봉사
- SQL
- BFS
- 백준알고리즘
- softeer
- 데이터베이스
- 코딩교육봉사
- python
- 스프링
- C++
- CJ UNIT
- 소프티어
- Today
- Total
JIE0025
[WhiteShip][3주차] 연산자 본문
WhiteShip Java Live Study 의 커리큘럼을 따라 개인적으로 공부한 내용입니다.
Codestates BE 42 : Study, Commercise 01 Java
Thanks to
" Codestates_SEB_BE_42 : Commercise "
강지은, 김례화, 전진우, 주대경
22.11.02
3주차 : 연산자
목차
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
✅ 산술 연산자
+, -, *, / (사칙연산) + %, ++, --
- 산술 연산자의 동작은 우리가 알고 있는 일반적인 수학 연산과 거의 동일
- 연산은 왼쪽에서부터 오른쪽으로 진행 함
✅ 비트 연산자
피연산자를 비트 단위로 논리연산한다. (이진수로 표현하고 논리연산)
비트 연산자 | 설명 |
& | 대응되는 비트가 모두 1이면 1을 반환함. (비트 AND 연산) |
| | 대응되는 비트 중에서 하나라도 1이면 1을 반환함. (비트 OR 연산) |
^ | 대응되는 비트가 서로 다르면 1을 반환함. (비트 XOR 연산) |
~ | 비트를 1이면 0으로, 0이면 1로 반전시킴. (비트 NOT 연산, 1의 보수) |
<< | 명시된 수만큼 비트들을 전부 왼쪽으로 이동시킴. (left shift 연산) |
>> | 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴. (right shift 연산) |
>>> | 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 됨. |
TCP SCHOOL.com 에서 가져온 이미지
⏺ 시프트 연산자
비트 이동 연산자는 정수 데이터의 비트를 왼쪽 또는 오른쪽으로 이동시키는 연산을 함
기호 | 설명 | 예시 |
<< | 왼쪽 항을 왼쪽으로 오른쪽 항만큼 시프트 | a << 2 |
>> | 왼쪽 항을 오른쪽으로 오른쪽 항만큼 시프트 | a >> 2 |
>>> | >>와 동일 (단, unsigned 부호없음) | a >>> 2 |
왼쪽으로 Shift 한번 == *2
오른쪽으로 Shift 한번 == /2
그림 1)
num = 2인데 왼쪽으로 shift 2 되어 곱하기 4와 같아 8로 변했다.
00010 ⏩ 01000
그림 2)
num = 40인데 오른쪽으로 shift 2되어, 나누기 4와 같아 10으로 변했다.
0101000 ⏩ 0001010
⏺ >> vs >>>
>> 와 >>>는 양수를 계산할 때는 차이가 없지만, 음수를 계산할 때 차이가 남.
>> 는 시프트 연산을 하고 빈 공간을 1로 채움.
>>>는 시프트 연산을 수행하고 빈 공간을 0으로 채움 (때문에 - 부호가 사라져서 + 부호가 됨)
✅ 관계 연산자 (=비교 연산자)
두 값을 비교하는 데 사용.
비교 반환값 : true, false ( boolean 값 )
✅ 논리 연산자
주어진 논리식을 판단하여, 'true', 'false'를 결정하는 연산자
AND ( && ) , OR ( || )
- 두 개의 피연산자를 가지는 이항 연산자
- 연산 방향 : 왼쪽에서 오른쪽
NOT ( ! )
- 연산자는 피연산자가 단 하나 뿐인 단항 연산자
- 연산 방향 : 오른쪽에서 왼쪽
- && : 논리식이 모두 true이면 true 를 반환 (AND 연산)
- || : 논리식 중에 하나라도 true이면 true 를 반환(OR 연산)
- ! : 논리식의 결과가 참이면 거짓을, 거짓이면 참을 변환함 (NOT 연산)
✅ 복합 대입 연산자 Assignment(=) Operator
기호 | 설명 | 풀이 |
+= | 좌변의 변수 + 연산하고 좌변에 할당 | a = a + 1 |
-= | 좌변의 변수 - 연산하고 좌변에 할당 | a = a - 1 |
*= | 좌변의 변수 * 연산하고 좌변에 할당 | a = a * 1 |
/= | 좌변의 변수 / 연산하고 좌변에 할당 | a = a / 1 |
%= | 좌변의 변수 % 연산하고 좌변에 할당 | a = a % 1 |
&= | 좌변의 변수 & 연산하고 좌변에 할당 | a = a & 1 |
^= | 좌변의 변수 ^ 연산하고 좌변에 할당 | a = a ^ 1 |
ㅣ = | 좌변의 변수 ㅣ 연산하고 좌변에 할당 | a = a ㅣ 1 |
<<= | 좌변의 변수 << 연산하고 좌변에 할당 | a = a << 1 |
>>= | 좌변의 변수 >> 연산하고 좌변에 할당 | a = a >> 1 |
>>>= | 좌변의 변수 >>> 연산하고 좌변에 할당 | a = a >>> 1 |
⏺ 복합 대입 연산자 예제
✅ instanceof
변수가 참조하고 있는 객체의 실제타입을 확인하기 위해 사용하는 연산자
- 형변환이 가능한지 여부를 알기 위해 사용
- boolean (true/false) 타입을 이용해 결과값 반환
참조변수 instanceof 타입/class명
//결과 : boolean
⏺언제 사용할까?
(설명용으로 급하게 만든 예시입니다..)
자동차 <- 현대자동차 <- A , B, C (대문자영어 : 차 종류) — a, b, c (소문자영어 : 차 종류별 인스턴스)
현대자동차 기업이 운영하지만, 어떤차든 이용할 수 있는 서비스를 만들었음
근데 현대 자동차에만 어떤 동작을 시키려고 함
이럴때 인스턴스a가 현대자동차(객체)인지 확인한다.
if( a instanceof 현대자동차) {
// 어떤 동작
}
⏺ 상위클래스와 하위클래스의 관계
변수의 타입 클래스가 다른 클래스를 상속받는 클래스인 경우, 상위클래스를 대상으로 instanceof 연산 수행하면, true반환
[하위클래스instance] instanceof [상위클래스]
예제코드
* redBeanBreadMachine을 만들고 싶었는데 급하게 코드 작성하느라 redBeanFishBread가 되어버림..
(팥빵기계로 자연스럽게 읽으시길...)
public class Main {
public static void main(String[] args) {
BreadMachine myMachine = new BreadMachine();
System.out.println(myMachine instanceof BreadMachine);
System.out.println(myMachine instanceof redBeanFishBread);
BreadMachine yourMachine = new redBeanFishBread();
System.out.println(yourMachine instanceof BreadMachine);
System.out.println(yourMachine instanceof redBeanFishBread);
}
public static class BreadMachine{
public BreadMachine(){
//만능 빵을 만들어내는 기계 (생성자)
}
}
public static class redBeanFishBread extends BreadMachine {
public redBeanFishBread(){
//팥빵만 생성 가능한 기계 (생성자)
}
}
}
- 코드를 보면, 자식클래스가 부모를 선택하는것을 볼 수 있음 // (팥빵기계) extends (빵기계)
⏺ 인터페이스와 클래스(구현부)의 관계
인터페이스를 구현하는 클래스의 경우 인터페이스를 대상으로 instanceof 연산 수행하면, true반환
[구현 클래스] instanceof [인터페이스]
public class Main {
public static void main(String[] args) {
//연산 수행 [class instance] instanceof [interface]
System.out.println(myMachine instanceof Machine);
System.out.println(yourMachine instanceof Machine);
// yourMachine instanceof 연산자로 Machine 으로 바꿀 수 있음을 알았다
// yourMachine에 myMachine을 할당해보고 출력해보자.
myMachine.run();
myMachine.stop();
System.out.println();
yourMachine.run();
yourMachine.stop();
yourMachine = myMachine;
yourMachine.run();
yourMachine.stop();
}
public interface Machine{
// 인터페이스는 -- 필요한 기능과 변수를 강제함.
// 기계의 경우 공통적으로 <동작한다. 멈춘다> 등의 기능이 있을 수 있음
// run() ,stop() ...
// 기계의 경우 공통적으로 <전원상태, 제작년도> 등의 변수가 있을 수 있음
// boolean onState, string date ...
public boolean onState =false;
public void run();
public void stop();
}
public static class BreadMachine implements Machine{
public BreadMachine(){
//만능 빵을 만들어내는 기계 (생성자)
}
@Override
public void run(){
System.out.println("빵기계가 동작합니다.");
}
@Override
public void stop(){
System.out.println("빵기계를 멈춥니다.");
}
}
public static class redBeanFishBread extends BreadMachine {
public redBeanFishBread(){
//팥빵만 생성 가능한 기계 (생성자)
}
@Override
public void run(){
System.out.println("팥빵기계가 동작합니다.");
}
@Override
public void stop(){
System.out.println("팥빵기계를 멈춥니다.");
}
}
}
✅ ( → )화살표 연산자
- 람다 표현식을 구성하는 데 사용
람다를 알기위해 추가로 필요한 내용들...😂😂
⏺ 익명함수
- 람다식은 함수의 이름 없이 사용되기때문에 익명함수라고 불리기도 한다.
- (사실은 익명객체이다.)
⏺ 람다식에 대한 간략한 이해
- 하위 내용은 화살표 연산자에 대한 조사로 인해 람다가 무엇인지, 어떻게 이루어지는지 가볍게이해하기 위한 정리글
- 람다의 정확한 개념과 활용을 위한 지식은 추후에 다룰 예정
- 람다식의 타입과 형변환
- 람다식의 외부 변수 참조
- java.util.function 패키지
- 메서드 참조 등
⏺ 람다식 소개
람다란
자바의 큰 두가지 변화
1) JDK 1.5부터의 Generics ( 제네릭 )
2) JDK 1.8부터의 Lambda expression ( 람다식 )
- 람다식의 도입으로 인해 자바는 객체지향 언어임과 동시에 함수형 언어의 기능을 갖출 수 있었다.
- 람다는 특정 클래스에 속하지 않고도 사용 가능
- 그래서 클래스 내에 속하는 함수라는 의미를 내포하는 메서드라는 용어 대신 함수라는 용어를 채택
- 람다는 메서드를 하나의 식으로 표현한 것
// 일반 메서드
int max (int a, int b) {
return a > b ? a : b;
}
// max() 와 같은 역할을 하는 람다 표현식
(a, b) -> a > b ? a: b
// -------------------------------------------
// 일반메서드
void printVar(String name, int i) {
System.out.println(name + " = " + i);
}
// printVar() 와 같은 역할을 하는 람다식
(name, i) -> System.out.println(name + "=" + i)
장점
- 간결면서도 이해하기 쉽다.
- 함수를 정의하기 위해 클래스를 새로 만들 필요없이 필요시 바로 람다식을 통한 메서드 역할 수행이 가능하다.
- 람다식을 사용하여 메서드를 변수처럼 다루는것이 가능하다.
- 람다식은 다른 메서드의 매개변수로 전달되어지는것이 가능하다.
- 람다식은 메서드의 결과로 반환되는것이 가능하다.
단점
- 지나치게 남발하면 코드가 이해하기 어렵고 지저분해짐.
- 람다를 사용하여 만든 무명함수는 재사용이 불가능함.
⏺ 람다에서의 타입추론
- 자바 컴파일러가 타입을 추론하는 것을 타입추론이라고 한다.
(컴파일러는 타입을 추론하기 위해 메서드 호출과 이에 상응하는 선언부를 살펴 봄) - 람다식에 선언된 매개변수의 타입은 추론이 가능한 경우 생략이 가능
- 반환타입이 없는 이유 역시 추론이 가능하기 때문
** 추후 람다파트( Whiteship Java Live Study 15주차 )에서 자세히 기술
⏺ Anonymous class 익명클래스
- 이름이 없는 클래스 (조상의 클래스이름 또는 인터페이스 이름을 통해 정의)
- 클래스의 선언 + 객체생성 (동시에)
- 따라서 한번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있음 (일회용)
- 사용예
class Example {
// 익명클래스 정의 형태
Object annyClass01 = new Object() { void methodEx() {}};
static Object annyClass01 = new Object() { void methodEx() {}};
void methodNormal(){
Object annyClass02 = new Object() { void methodEx() {}};
}
}
// 익명클래스 사용 X
public class NoAnny {
public static void main(String[] args) {
Button buttonStart = new Button("Start");
buttonStart.addActionListener(new **EventHandler**());
}
}
class **EventHandler** implements **ActionListener** {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent Occurred !!! ");
}
}
//---------------------------------------------------------------
// 익명클래스 사용시
public class YesAnny {
public static void main(String[] args) {
Button buttonStart = new Button("Start");
buttonStart.addActionListener(new **ActionListener**() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent Occurred !!! ");
}
});
}
}
//---------------------------------------------------------------
//---------------------------------------------------------------
interface **MyFunction** {
public abstract int max(int a, int b);
}
// ...생략 main()
MyFunction f = new **MyFunction**() {
@Override
public int max(int a, int b) {
return a > b ? a : b;
}
};
int maxNum = f.max(3, 50);
// ...생략
⏺ 함수형 인터페이스
이해
* 람다식은 어떤 클래스에 포함되어있을까
* 자바에서 모든 메서드는 클래스 내에 포함되어야한다.
- 사실 람다식은 익명 클래스의 객체와 동등하다.
- 익명클래스에서의 메서드 호출과 마찬가지로 람다식이 익명클래스의 객체와 동등하다면 -- 같은 방법으로 호출 가능
- MyFunction 인터페이스를 구현한 익명 객체를 람다식으로 대체 가능한 이유
- 람다식도 실제로는 익명 객체이기때문
- MyFunction 인터페이스를 구현한 익명 객체의 메서드 max() 와
- 람다식의 매개변수의 타입과 갯수 , 반환값이 일치하기 때문
- 위와 같은 사실들을 통해 하나의 메서드가 선언된 인터페이스를 정의해서 람다식을 다루면 기존의 자바의 규칙들을 어기지 않으면서 자연스럽게 구현 가능
→ 람다식을 다루기 위한 인터페이스 : Functional Interface (함수형 인터페이스)
→ 따라서 인터페이스를 통해 람다식을 다루기로 결정
함수형 인터페이스
@FunctionalInterface
interface MyFunction{
public abstract int max(int a, int b);
}
// 함수형 인터페이스를 참조변수로 사용 : MyFunction f
MyFunction f = () -> System.out.println("myMethod is occurred !!!");
함수형 인터페이스는 오직 하나의 추상 메서드만 정의되어있어야 한다.
- 람다식과 인터페이스의 메서드가 1:1 로 연결되어야 하기 때문
- static 메서드와 defualt 메서드의 개수는 제약이 없다.
- @FunctionalInterface 을 붙이면 컴파일러가 함수형 인터페이스 정의를 검사해준다.
⏺ 람다식의 사용예시
- 람다식은 매개변수로 사용 가능
@FunctionalInterface
interface MyFunction{
public abstract int max(int a, int b);
}
// --------------------------생략
// 다음과 같이 함수형 인터페이스가 어떤 메서드의 매개변수 형으로 선언되어있을때
void aMethod(MyFunction f) {
f.myMethod();
}
// --------------------------생략
MyFunction f = () -> System.out.println("myMethod is occurred !!!");
// 람다식을 참조하는 참조변수가 매개변수로 지정될 수 있다.
aMethod(f);
// 또는 다음과 같은 방식 역시 가능하다.
aMethod(() -> System.out.println("myMethod is occurred !!!"));
- 람다식은 반환될 수 있다.
@FunctionalInterface
interface MyFunction{
public abstract int max(int a, int b);
}
// --------------------------생략
// 다음과 같이 함수형 인터페이스가 어떤 메서드의 매개변수 형으로 선언되어있을때
MyFunction myMethod() {
MyFunction f = () -> {};
// 람다식을 가리키는 참조변수를 return
return f;
// 또는 다음과 같은 방식 역시 가능
return () -> {}; // myMethod 함수의 리턴타입이 지정되어있으므로 가능
}
화살표 연산자가 왜이리 깊어졌을까 ㅠㅠ
✅ 삼항 연산자
유일하게 세 개의 항으로 만들어진 연산자
구조
👉🏻 조건식 ? 반환값1 : 반환값2 => 조건식이 true일 경우 반환값1의 값을 반환, false일 경우 반환값2의 값을 반환.
ex)
int a = 10 , int b= 20 //일 때, a > b ? a : b ; //조건식이 ``false`` 이므로 b 반환
cf) 삼항 연산자의 중첩
(조건A)?(조건B)?(반환값A):(반환값B):(반환값C)
- 우선, (조건A) 가 true인지 false 인지 판단.
- false이면 (반환값C) 반환.
- (조건A)가 true일 경우, (조건B)가 true 인지false 인지 판단하여 반환. true 일 경우 : 반환값 A false 일 경우 : 반환값 B
✅ 연산자 우선 순위
- 단항, 이항, 삼항 연산자 순으로 우선순위를 갖는다.
- 산술, 비교, 논리, 대입 연산자 순으로 우선순위를 갖는다.
- 단항과 대입 연산자를 제외한 모든 연산 방향은 왼쪽에서 오른쪽이다.
- 복잡한 연산식에는 ()괄호를 사용해서 우선순위를 정해준다.
(optional) Java 13. switch 연산자
✅ switch 연산자
⏺ 기존 switch
- 값을 return하고 싶으면 result 변수를 만들어 주어야 함
- multiple case는 지원하지 않음 case 1: case 2: 이런식으로 붙힘.
- 다수의 case와 break가 존재하고, break를 빼먹을 경우 다음 분기로 넘어가게 됨
int test(int num) {
int result = 0;
switch(num){
case 1:
case 2:
result = 1;
break;
case 3:
case 4:
result = 2;
break;
default:
result = 3;
break;
}
return result;
}
⏺ Java 13. switch연산자
- 문장이 아닌, 식으로 가능해서 return값으로 사용 가능하다. (switch문 뒤에 세미콜론; 쓰기)
- 값을 return할 때 yield 키워드 사용 (자바 13)
- multiple case를 지원한다.
- -> 사용 가능 (자바 12)
int test(int num) {
return switch (num) {
case 1, 2:
yield 1;
case 3, 4:
yield 2;
default:
yield 3;
};
}
⏺ Java 12. switch 연산자
- : 대신 -> 를 사용
- multicase : 여러 조건을 , 로 구분해 한번에 처리 가능
- break문 생략 가능
- -> 를 사용했다면, 실행문이 2개이상이거나, 반환값이 존재할 경우 { } 를 사용해야 함.
- : 를 사용했다면, 실행문이 여러개여도 { } 사용하지 않아도 됨.
public class Main {
public static void main(String[] args) {
System.out.println(condition_check("soso"));
System.out.println(condition_check("sad"));
System.out.println(condition_check("happy"));
System.out.println(condition_check2("soso"));
System.out.println(condition_check2("sad"));
System.out.println(condition_check2("happy"));
}
// -> 사용
public static String condition_check(String emotion){
return switch (emotion){
case "happy", "fun" -> "best";
case "sad", "angry" -> "not good";
default -> "--";
};
}
//yield 사용
public static String condition_check2(String emotion){
return switch (emotion){
case "happy", "fun": yield "best";
case "sad", "angry": yield "not good";
default: yield "--";
};
}
}
references
남궁성 - 자바의 정석
https://live-everyday.tistory.com/207
https://www.w3schools.com/java/java_operators.asp
http://www.tcpschool.com/java/java_operator_logic
https://www.w3schools.com/java/java_operators.asp https://kephilab.tistory.com/28
https://velog.io/@eledev/JAVA-STUDYwith-whiteship-3주차
https://gintrie.tistory.com/63
'개발 > Java, Kotlin' 카테고리의 다른 글
[WhiteShip][8주차] 인터페이스 (0) | 2022.11.10 |
---|---|
[WhiteShip][7주차] 패키지 (0) | 2022.11.08 |
[WhiteShip][2주차] 자바 데이터 타입, 변수 그리고 배열 (0) | 2022.11.02 |
[WhiteShip][1주차] JVM과 자바코드 (0) | 2022.10.30 |
[Spring Framework] 기초공부 (0) | 2020.02.03 |