18일차 09/15 2022

SangYu Lee·2022년 9월 17일
0

codestates backend

목록 보기
18/30

keyword - Annotation, Lambda, Stream, I/O

1. Annotation

주석(comment)은 소스 코드를 읽는 ‘사람’에게 정보를 제공하는 반면, 애너테이션(Annotation)은 특정 코드를 사용하는 ‘프로그램’에게 정보를 전달하는 것이다.

기능

  • 컴파일러에게 문법 에러를 체크하도록 정보를 제공

  • 프로그램을 빌드할 때 코드를 자동으로 생성할 수 있도록 정보를 제공

  • 런타임에 특정 기능을 실행하도록 정보를 제공

애너테이션의 용도와 종류

표준 애너테이션
자바에서 기본적으로 제공하는 애너테이션
@Override
컴파일러에게 메서드를 오버라이딩하는 것이라고 알림
@Deprecated
앞으로 사용하지 않을 대상을 알릴 때 사용
@FunctionalInterface
함수형 인터페이스라는 것을 알
@SuppressWarning
컴파일러가 경고메세지를 나타내지 않음

메타 애너테이션
애너테이션을 정의하는 애너테이션
@Target
애너테이션을 정의할 때 적용 대상을 지정하는데 사용한다.
@Documented
애너테이션 정보를 javadoc으로 작성된 문서에 포함시킨다.
@Inherited
애너테이션이 하위 클래스에 상속되도록 한다.
@Retention
애너테이션이 유지되는 기간을 정하는데 사용한다.
@Repeatable
애너테이션을 반복해서 적용할 수 있게 한다.

사용자 정의 애너테이션
애너테이션을 정의하는 방법은 인터페이스를 정의하는 것과 비슷하다.

@interface 애너테이션네임 { 
	타입 요소명(); // 애너테이션 요소를 선언
}

2. Lambda

함수형 프로그래밍 기법을 지원하는 자바의 문법요소. 익명함수라고도 하며 메서드를 하나의 ‘식(expression)’으로 표현한 것으로, 코드를 매우 간결하면서 명확하게 표현할 수 있다

  • 반환값이 있는 메서드의 경우에는 return문과 문장 뒤에 오는 세미콜론(;)을 생략

  • 실행문이 하나만 존재할 때 중괄호를 생략

  • 매개변수 타입을 쉽게 유추할 수 있는 경우에는 매개변수의 타입을 생략

사실 메서드는 클래스 없이 존재할 수 없다. 그래서 함수형 인터페이스를 구현한 '익명 객체'라고 람다식을 이해해야 한다.

// sum 메서드 람다식
(num1, num2) -> num1 + num2

// 람다식을 객체로 표현
new Object() {
	int sum(int num1, int num2) {
		return num1 + num1;
	}
}

Object ob = new Object() {
	int sum(int num1, int num2) {
		return num1 + num1;
	}
}

ob.sum(1,3) // 사용불가 sum이라는 함수가 Object 클래스에 없음.

그러나 Object라는 클래스에 sum이라는 함수를 구현한 것이 아니기 때문에, 참조변수 ob에 위 익명 클래스를 담더라도 sum이라는 함수를 사용할 수가 없다.

그렇다면 자바 개발자들은 어떻게 구현하기로 했을까?
=> 함수형 인터페이스를 만들고 그 안에 있는 메서드를 활용하기로 했다.

람다식 또한 객체이기 때문에, 인터페이스의 추상메서드를 구현할 수 있기 때문이다.
객체의 생성과 동시에 함수형 인터페이스의 추상메서드를 구현하기

함수형 인터페이스 타입으로 참조변수를 선언하고 할당연산자 오른쪽에 람다식으로 메서드 내용을 구현하기.

public static void main(String[] args) {
	ExampleFunction exampleFunction = (num1, num2) -> num1 - num2
	System.out.println(exampleFunction.sub(10,15))
}

interface ExampleFunction {
	public abstract int sub(int num1, int num2);
}

함수형 인터페이스에는 단 하나의 추상 메서드만 선언될 수 있는 데, 람다식과 인터페이스의 메서드가 1:1로 매칭되어야 하기 때문.

기본함수형 인터페이스
https://codechacha.com/ko/java8-functional-interface/

 

메서드 레퍼런스
불필요한 매개변수를 제거할 때 주로 사용 입력값과 출력값의 반환타입을 쉽게 유추할 수 있을 때 생략

(a, b) -> Math.min(a, b);
IntBinaryOperator op = Math :: min; //메서드 참조

정적, 인스턴스 메서드 참조, 생성자 참조도 가능하다.

클래스 :: 메서드 // 정적 메서드인 경우
인스턴스 :: 메서드 // 인스턴스 메서드인 경우
클래스 :: new // 생성자 메서드인 경우

3. Stream

배열, 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 반복자
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

스트림의 특징

  • 선언형으로 데이터 소스를 처리한다.

  • 중간 연산과 최종 연산을 할 수 있다.

  • 람다식으로 요소 처리 코드를 제공한다.

  • 내부 반복자를 사용하므로 병렬 처리가 쉽다.

  • 스트림은 데이터를 변경하지 않는다.

  • 스트림은 일회용이다.

스트림 생성
collection framework는 미리 구현된 stream()메서드를 사용하면 stream을 생성할 수 있고, 배열의 경우에는 Stream.of나 Arrays.stream 메서드를 사용해야 한다.

Stream<String> stream = Stream.of("a", "b", "c"); //가변인자
Stream<String> stream = Stream.of(new String[] {"a", "b", "c"});
Stream<String> stream = Arrays.stream(new String[] {"a", "b", "c"});
Stream<String> stream = Arrays.stream(new String[] {"a", "b", "c"}, 0, 3); 
//end 범위 미포함

스트림 중간연산
filter(), distinct(), map(), flatMap(), sorted(), sorted(Comparator.reverseOrder(), peek()

스트림 최종연산
allMatch(), anyMatch(), noneMatch(), sum(), count(), average(), max(), min(), reduce(), collect()

Optional<T>
Optional은 모든 타입을 담을 수 있는 wrapper 클래스이다.

public final class Optional<T> {
	private final T value; // T타입의 참조변수
}

Optional 객체를 생성하려면 of() 또는 ofNullable()을 사용
Optional 객체에 객체에 저장된 값을 가져오려면 get()을 사용

  • 참조변수의 값이 null일 가능성이 있다면 orElse()메서드를 사용해 디폴트 값을 지정할 수 있다.

위에서 보았던 스트림의 average(), max(), min()등의 함수는 반환 타입이 Optional 타입이다. 그러므로 average()함수를 사용한 후에 getAsDouble이나 getAsInt같은 타입으로 지정된 값을 받아오거나, orElse(기본값)을 통해서 스트림에 값이 없을 경우를 미리 예외처리해야한다.

average().orElse(0.0)이후에 .getAsDouble()이란 메소드는 왜 붙일 수 없을까
->orElse로 0.0이라는 원시값이 나오면 객체를 인자로 받는 getAsDouble에 넣을 수 없다.

4. 파일 입출력(I/O)

InputStream, OutputStream
바이트 기반의 입출력을 담당하는 스트림

  • try/catch 문 사용해서 예외처리 해야한다

  • BufferedStream 이라는 보조스트림으로 감싸서 효율을 높인다.

  • 읽을 때는 read()라는 메서드를 while문 안의 조건으로 사용하여 -1을 반환하면 종료하게 조건을 걸어놓고 쓴다.

  • 쓸 때는 byte 배열에 getBytes()라는 메서드를 사용하여 받은 다음에 write(byte배열) 메서드를 사용해서 작성한다.

  • 다 쓰고 나면 close()메서드도 실행해야 한다.

FileReader / FileWriter
2byte(자바기본단위) 문자 입출력 스트림
인코딩 <-> 유니코드 간의 변환
메서드는 위에 적은거랑 같다.

File 클래스

File file = new File("./", "newFile.txt"); //파일 인스턴스만 생성
file.createNewFile(); //메서드를 통해 실제로 파일 생성

메서드 종류 https://docs.oracle.com/javase/7/docs/api/java/io/File.html

profile
아이스커피

0개의 댓글