맞는데 왜 틀릴까..?

Java 108

[Effective Java] Item 45. 스트림은 주의해서 사용하라

스트림 스트림 API는 다량의 데이터 처리 작업을 돕고자 자바 8에 추가되었다. 컬렉션과 다르게 요소(element)를 저장하는 자료구조가 아닌, 데이터의 흐름을 처리하고 변환하는 파이프라인이다. 스트림은 데이터를 다루는 연산들을 조합하여 복잡한 처리 과정을 간결하고 가독성 있게 표현할 수 있다. 또한 내부적으로 데이터를 병렬로 처리하여 성능을 향상할 수 있는 장점도 가지고 있다. 스트림 안의 데이터 원소들은 객체 참조나 기본 타입 값(int, long, double)이다. 1. 데이터 소스 스트림은 컬렉션, 배열, I/O 채널 등 다양한 데이터 소스에서 생성할 수 있다. 2. 파이프라인 스트림은 연속된 작업들의 파이프라인으로 구성된다. 파이프라인은 데이터 소스에서 시작하여 중간 연산(intermedia..

Java/Effective Java 2023.07.08

[Effective Java] Item 44. 표준 함수형 인터페이스를 사용하라

자바가 람다를 지원하면서 API를 작성할 때 기존의 오버라이딩을 통한 템플릿 메서드 패턴보다, 같은 효과의 함수 객체를 받는 정적 팩토리나 생성자를 제공하는 방식이 좋아졌다. 함수형 인터페이스는 람다식으로 만든 객체에 접근하기 위해서 사용한다. 불필요한 함수형 인터페이스 표준 함수형 인터페이스를 사용 함수형 인터페이스 함수형 인터페이스(Functional Interface)는 자바에서 함수형 프로그래밍을 지원하기 위한 개념이다.자바 8부터 함수형 인터페이스가 도입되었으며, 람다식과 메서드 참조를 활용하여 함수를 일급 객체로 다룰 수 있으며, 이를 통해 코드의 간결성과 가독성을 높일 수 있다.함수형 인터페이스는 딱 하나의 추상 메서드를 가지는 인터페이스로, 이 추상 메서드를 함수형 인터페이스의 시그니처라고..

Java/Effective Java 2023.07.08

[Effective Java] Item 43. 람다보다는 메서드 참조를 사용하라

람다보다도 더 함수 객체를 간결하게 만드는 방법이 메서드 참조(method reference)다. 어떤 람다에서는 매개변수의 이름 자체가 프로그래머에게 좋은 가이드가 되기도 한다. 이런 람다는 길이는 더 길지만 메서드 참조보다 읽기 쉽고 유지보수도 쉬울 수 있다. 람다로 할 수 없는일이라면 메서드 참조로도 할 수 없다. 메서드 참조의 5가지 유형 1. 정적 메서드를 가리키는 메서드 참조 2. 인스턴스 메서드를 참조하는 수신 객체(참조 대상 인스턴스)를 특정하는 한정적 인스턴스 메서드 참조 Calculator의 인스턴스를 생성하고 해당 인스턴스를 사용하여 한정적 인스턴스 메서드 참조를 생성한다. addFunction은 Calculator의 add 메서드를 참조하고 있으며 subtractFunction은 C..

Java/Effective Java 2023.07.08

[Effective Java] Item 42. 익명 클래스보다는 람다를 사용하라

익명 클래스 자바에서 익명 클래스는 이름이 없는 클래스로, 일회성으로 사용되는 클래스를 간편하게 정의할 수 있는 기능이다. 익명 클래스는 클래스 선언과 동시에 인스턴스를 생성하여 사용한다. 주로 인터페이스나 추상 클래스를 구현하거나 확장하는 데 사용되는데, 이를 이용하면 클래스를 별도로 정의하고 이름을 부여하지 않고도 필요한 구현을 작성할 수 있다. 익명 클래스 예 문자열을 길이순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스를 사용하였다. 람다 익명 클래스 방식은 코드가 너무 길기 때문에 람다식을 이용해 어떤 동작을 하는지 명확하게 나타낼 수 있도록 하자. 람다식을 함수 객체로 사용한 예제 위 익명 클래스로 작성한 정렬을 람다식으로 대체한 예제이다. 람다, 매개변수, 반환값의 타입은 각각 Com..

Java/Effective Java 2023.07.02

[Effective Java] Item 41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라

마커 인터페이스 마커 인터페이스 : 아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해 주는 인터페이스 Ex) Serializable은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 직렬화 할 수 있다고 알려준다. 마커 인터페이스는 두 가지면에서 마커 애너테이션 보다 낫다. 1. 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있으나, 마커 애너테이션은 그렇지 않다. 마커 인터페이스는 어엿한 타입이기 때문에, 마커 애너테이션을 사용했다면 런타임에야 발견될 오류를 컴파일 타임에 잡을 수 있다. 자바의 직렬화는 Serializable 마커 인터페이스를 보고 그 대상이 직렬화할 수 있는 타입인지 확인한다. 위 예에서..

Java/Effective Java 2023.06.30

[Effective Java] Item 40. @Override 애너테이션을 일관되게 사용하라

@Override 애너테이션의 장점 아래 코드는 어떤 문제가 있을까? 중복을 허용하지 않는 Set에 26개의 소문자를 10번 반복해 추가했으니 집합의 크기는 26이 출력되어야 하지만 260이 출력된다. 해당 equals는 재정의(overriding)한것이 아니라 다중정의(overloading) 한 것이다. Object의 equals를 재정의하려면 매개변수 타입을 Object로 해야 하는데 그렇지 않아서 별개인 equals를 새로 정의한 것이 되었다. Object의 equals는 == 연산자처럼 객체 식별성만을 확인하여 같은 문자를 소유한 바이그램 10개가 각각 서로 다른 객체로 인식되어 260을 출력한 것이다. 여기서 만약 @Override를 달았다면 컴파일러가 해당 오류를 찾아내주었을 것이다. 이렇게 ..

Java/Effective Java 2023.06.30

[Effective Java] Item 39. 명명 패턴보다 애너테이션을 사용하라

명명 패턴의 단점 테스트 메서드 이름을 test로 시작했을 때 단점 (명명 패턴) 오타 - 실수로 tsetSafetyOverride로 지으면 테스트 프레임워크가 무시하고 지나친다 올바른 프로그램 요소에서만 사용되리라 보증할 방법이 없다. (클래스 이름을 TestSafetyMechanisms로 지었을 때 Junit은 클래스 이름에 관심이 없다.) 프로그램 요소를 매개변수로 전달할 방법이 없다. (특정 예외를 던져야만 성공하는 테스트가 있을 때, 기대하는 예외 타입을 테스트에 전달해야 한다.) Test 애너테이션 메타애너테이션 애너테이션 선언에 다는 애너테이션이다. Ex) @Retention(RetentionPolicy.RUNTIME) : @Test가 런타임에도 유지되어야 한다는 표시 @Target(Elem..

Java/Effective Java 2023.06.30

[Effective Java] Item 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

열거 패턴의 확장 타입 안전 열거 패턴은 열거한 값들을 그대로 가져온 다음 값을 더 추가하여 다른 목적으로 쓸 수 있지만 열거 패턴은 그럴 수 없다. 열거 타입을 확장하는 것은 좋지 않은 선택이지만 연산 코드 등 최소한의 쓰임새가 있다. 타입 안전 열거 패턴 타입 안전 열거 패턴은 열거 타입을 확장하여 더 많은 기능과 유연성을 제공하는 방식이다. 추가 정보를 가지는 필드와 메서드를 사용하여 상수에 대한 정보를 표현할 수 있고, 상수 집합을 제한하여 원하는 인스턴스만 생성할 수 있다. 이에 반해, 일반적인 열거 타입은 단순한 상수 값의 집합으로 사용되며, 추가 정보나 인스턴스 생성 제한 기능은 제공하지 않는다. 타입 안전 열거 패턴의 경우 ExtendedOperation 클래스를 정의하고 각 상수를 해당 ..

Java/Effective Java 2023.06.29

[Effective Java] Item 37. ordinal 인덱싱 대신 EnumMap을 사용하라

Ordinal ordinal은 Enum 타입의 객체에서 사용되는 메서드로 Enum 상수가 정의된 순서를 반환한다. Enum 상수는 0부터 시작하는 정수값을 가지며, 상수가 정의된 순서대로 0부터 1씩 증가한다. 해당 예제는 Weekday라는 Enum 타입을 정의하였으며, ordinal 메서드를 사용하여 WEDNESDAY 상수의 순서를 반환해 2를 출력한다. ordinal()을 배열 인덱스로 사용 시 문제점 이처럼 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드로 인덱스를 얻는 코드가 있다. 해당 코드는 집합들을 배열하나에 넣고 enum의 ordinal 값을 그 배열의 인덱스로 사용하는 경우이다. 배열은 제네릭과 호환되지 않으니 비검사 형변환을 수행해야 한다. 배열은 인덱스의 의미를 모르니 출력 ..

Java/Effective Java 2023.06.29

[Effective Java] Item 36. 비트 필드 대신 EnumSet을 사용하라

열거한 값들이 주로 단독이 아닌 집합으로 사용될 경우, 예전에는 각 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용해 왔다. 비트 필드 비트 필드 열거 상수 아래처럼 비트별 OR를 사용해 여러 상수를 하나의 집합으로 모을 수 있으며, 이렇게 만들어진 집합을 비트 필드라 한다. text.applyStyles(STYLE_BOLD | STYLE_ITALIC); 비트 필드를 사용하면 비트별 연산을 사용해 합집합과 교집합 같은 집합 연산을 효율적으로 수행할 수 있다. 비트 필드는 정수 열거 상수의 단점을 그대로 지닌다. 비트 필드 값이 그대로 출력되면 단순한 정수 열거 상수를 출력할 때보다 해석하기 훨씬 어렵다. 비트 필드 하나에 녹아 있는 모든 원소를 순회하기도 까다롭다. 최대 몇 비트가 필..

Java/Effective Java 2023.05.16