java

    로 타입은 사용하지 말라 - [5장. 제네릭(아이템26)]

    이번 장(5장)부터는 제네릭을 다룬다. 혹시나 제네릭에 대한 기본 개념이 필요하다면 이전 글을 먼저 보고 오도록 하자. 1. 로 타입 (Raw Type) 개념 💽 로 타입이란 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말한다. 예를 들어 List의 로 타입은 List다. 2. 로 타입을 사용하면 안 되는 이유 💾 제네릭이 안겨주는 안전성과 표현력을 고려할 때 로 타입은 절대로 써서는 안 된다. 로 타입을 사용하는 코드(= 제네릭을 사용하지 않는 코드)와 로 타입을 사용하지 않는 코드(= 제네릭을 사용하는 코드)를 비교해 보자. 📒 1. 로 타입을 사용하는 경우 기본적인 동작은 numbers에 숫자를 넣고 반복문을 통해 들어간 숫자를 확인하려고 하는 코드다. 숫자가 들어가야 하지만 문자열이 ..

    제네릭(Generics) - 기본 개념

    JDK 1.5부터 도입된 제네릭(Generics)에 대해서 알아보자. '제네릭(Generic)을 사용하면 다양한 타입을 사용할 수 있다.' 정도로만 알고 있었는데 제대로 공부하려고 보니깐 생각보다 양이 많다. 쫌 많이 많다... 그래서 이번 글에서는 제네릭의 기번 개념에 대해서 알아보고 다음 글들을 통해 더 구체적으로 알아보는 것으로 하자. (이펙티브 자바 5장의 제네릭(아이템 26 ~ 아이템 33) 내용과 와일드카드 등의 내용을 추가적으로 다룰 예정이다.) (이펙티브 자바 5장 제네릭 파트를 읽으려는데 이해가 잘 되지 않아서 제네릭의 기본부터 블로깅하고 있는 중이다...😅) 1. 제네릭(Generic) 개념 🧱 우리는 제네릭(Generics)을 그 어떠한 개념보다 자주 사용한다. public stati..

    래퍼 클래스 (Wrapper Class)

    1. 개념 🚶‍♀️ 일반적으로 객체지향 개념에서 모든 것은 객체로 다루어져야 한다. 하지만 자바에서 8개의 기본형(boolean, char, byte, short, int, long, float, double)은 객체로 다루어지지 않는다. 자바가 완전한 객체 지향 언어가 아니라는 이야기를 듣지만, 보다 높은 성능을 얻을 수 있다는 장점이 있다. 프로그래밍을 하다 보면 기본형(Primitive Type) 변수도 어쩔 수 없이 객체로 다뤄야 하는 경우가 있다. 예를 들면, 매개변수로 객체를 요구할 때, 기본형 값이 아닌 객체로 저장해야 할 때, 객체 간의 비교가 필요할 때 등등의 경우에는 기본형 값들을 객체로 변환하여 작업을 수행해야 한다. 이럴 때 래퍼 클래스를 사용하여 각각의 타입에 해당하는 데이터를 인..

    톱레벨 클래스는 한 파일에 하나만 담으라 - [4장. 클래스와 인터페이스(아이템25)]

    소스 파일에 하나에 톱레벨 클래스(톱레벨 클래스란 파일에 정의되어 있는 가장 바깥에 있는 클래스를 말한다)를 여러 개 선언하더라도 컴파일할 때는 문제가 없다. 유효한 문법이라는 것이다. 하지만 이것은 아무런 득이 없을뿐더러 심각한 위험을 감수해야 한다. 그 이유는 한 소스 파일에 톱레벨 클래스를 여러 개 선언하면 컴파일 순서에 따라 결과가 달라질 수 있기 때문이다. 문제 상황에 대한 예시를 살펴보고, 해결책을 알아보도록 하자. 1. 문제점 💍 집기(Utensil)와 디저트(Dessert) 클래스가 Utensil.java라는 한 파일에 정의되어 있다고 하자. // Utensil.java class Utensil { static final String NAME = "pan"; } class Dessert {..

    태그 달린 클래스보다는 클래스 계층구조를 활용하라 - [4장. 클래스와 인터페이스(아이템23)]

    1. 태그 달린 클래스 🎧 태그 달린 클래스란 두 가지 이상의 의미를 표현할 수 있으며, 그중 현재 표현하는 의미를 태그 값으로 알려주는 클래스를 말한다. 아래 코드는 원과 사각형을 표현할 수 있는 태그 달린 클래스이다. public class Figure { enum Shape {RECTANGLE, CIRCLE}; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double width; // 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다. double radius; // 원용 생성자 Figure2(double radius){ shape = Shape.CIRCLE; this...

    인터페이스는 타입을 정의하는 용도로만 사용하라 - [4장. 클래스와 인터페이스(아이템22)]

    1. 인터페이스의 역할 🐣 인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다. 클래스가 어떤 인터페이스를 구현한다는 것은 자신의 인스턴스로 무엇을 할 수 있는지를 클라이언트에 얘기해 주는 것이다. 인터페이스는 오직 이 용도로만 사용해야 한다. (밑에서 살펴볼 것이지만 상수 공개용 수단으로 사용하지 말아야 한다.) 2. 상수 인터페이스 안티패턴 🐥 위에서 말한 인터페이스의 역할에 맞지 않는 예로 상수 인터페이스라는 것이 있다. 상수 인터페이스란 메서드 없이, 상수를 뜻하는 static final 필드로만 가득 찬 인터페이스를 말한다. public interface PhysicalConstants { // 아보가드로 수 (1/몰) static final double AVOGAD..

    인터페이스는 구현하는 쪽을 생각해 설계하라 - [4장. 클래스와 인터페이스(아이템21)]

    1. 개념 👻 디폴트 메서드를 선언하면, 그 인터페이스를 구현한 후 디폴트 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 된다. 기존 인터페이스에 메서드를 추가하는 길이 열렸지만 모든 기존 구현체들과 매끄럽게 연동되리라는 보장은 없다. 자바 7까지의 세상에서는 모든 클래스가 "현재의 인터페이스에 새로운 메서드가 추가될 일은 영원히 없다"라고 가정하고 장성됐으니 말이다. 디폴트 메서드는 구현 클래스에 대해 아무것도 모른 채 합의 없이 무작성 '삽입'될 뿐이다. 이번 글에서는 이런 경우 발생할 수 있는 문제 상황들을 살펴보고 그에 대한 해결책을 알아보자. 2. [문제 상황 1] 생각할 수 있는 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기란 어렵다. 🤖 자바 8의 Collcti..

    추상 클래스보다는 인터페이스를 우선하라(추상 골격 구현(Skeletal Implementation) 클래스)(2) - [4장. 클래스와 인터페이스(아이템20)]

    이전 글을 통해 인터페이스의 장점들을 알아보았다. 이번 글에서는 인터페이스와 골격 구현(skeletal implementation) 클래스를 함께 제공하여 인터페이스와 추상 클래스의 장점을 모두 취하는 방법을 알아보자. 인터페이스와 추상 클래스를 같이 사용했을 때의 장점은 '인터페이스에서 구현해 줄 수 있는 것들은 디폴트 메서드로 구현하고, 구현해 줄 수 없는 것들은 추상 골격 클래스에서 나머지 메서드를 구현한다.'는 것이다. 추상 골격 구현 클래스를 활용하였을 때 얻을 수 있는 2가지의 장점에 대해서 자세히 알아보자. (명칭과 관련하여, 추상 골격 클래스라고 부르는 이유는 일부만 구현하고 일부는 구현하지 않아도 되기 때문이다. 인터페이스가 뼈대 역할을 한다고 생각하면 쉬울 거 같다.) 장점 1. 단순히..

    추상 클래스보다는 인터페이스를 우선하라(인터페이스의 장점)(1) - [4장. 클래스와 인터페이스(아이템20)]

    자바가 제공하는 다중 구현 메커니즘은 '인터페이스와 추상 클래스' 2가지가 있다. 자바 8부터 인터페이스도 Default Method를 제공할 수 있기 때문에 두 메커니즘 모두 인스턴스 메서드를 구현 형태로 제공할 수 있다. 둘의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점이다. 자바는 단일 상속만 지원하니, 추상 클래스 방식은 새로운 타입을 정의하는 데 커다란 제약을 안게 되는 것이다. 반면 인터페이스가 선언한 메서드를 모두 정의하고 그 일반 규약을 잘 지킨 클래스라면 다른 어떤 클래스를 상속했든 같은 타입으로 취급된다. 여기까지가 추상클래스와 인터페이스에 대한 간단한 설명이다. 이번 글에서 인터페이스의 5가지 장점들을 살펴보면서 ..

    세그먼트 트리(Segment Tree)

    1. 개념 🛫 세그먼트 트리(Segment Tree)란 여러 개의 데이터가 존재할 때 특정 구간의 합을 구하는 데 사용하는 자료구조이다. 트리 종류 중 하나로 이진트리의 형태이며, 특정 구간의 합을 가장 빠르게 구할 수 있다는 장점이 있다. O(log N) 2. 동작방식 🚁 세그먼트 트리를 이용하기 위해서는 우선 '구간 합 트리'를 생성해야 한다. 그리고 '구간 합을 구하는 함수'와 '원소를 수정하는 함수'를 이용하여 구간 합을 구하고 특정 원소를 수정할 수 있다. '1 9 3 8 4 5 5 9 10 3 4 5'라는 12개의 원소를 가진 배열이 주어졌을 때 세그먼트 트리를 이용하여 구간 합을 구해보자. 1. 구간 합 트리 생성하기 '구간'은 원래 데이터 범위를 반씩 분할하는 것으로 설정한다. 최상단 노드..

    클래스와 멤버의 접근 권한을 최소화하라 - [4장. 클래스와 인터페이스(아이템15)]

    이번 글을 통해 '정보 은닉의 장점'과 '클래스와 인터페이스', '멤버(필드, 메서드, 중첩 클래스, 인터페이스)'의 접근 제한자 원칙에 대해서 알아보자. 1. 정보 은닉의 장점 🎸 정보 은닉의 장점은 정말 많은데 그중 대부분은 구현과 API를 분리시켜서 얻는 이점과 연관되어 있다. 정보 은닉의 장점은 아래와 같다. 시스템 개발 속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문이다. 시스템 관리 비용을 낮춘다. 각 컴포넌트를 더 빨리 파악하여 디버깅할 수 있고, 다른 컴포넌트로 교체하는 부담도 적기 때문이다. 정보 은닉 자체가 성능을 높여주지는 않지만, 성능 최적화에 도움을 준다. 완성된 시스템을 프로파일링해 최적화할 컴포넌트를 정한 다음, 다른 컴포넌트에 영향을 주지 않고 해당 컴포넌트만 최..

    카운팅 정렬 (Counting Sort)

    1. 개념 👑 '계수 정렬'이라고도 불리는 '카운팅 정렬(Counting Sort)'은 각 원소들이 몇 개씩 있는지 나타내는 count배열을 활용하는 정렬 알고리즘이다. 각 원소의 값이 count 배열의 인덱스가 되므로 '정수나 정수로 표현할 수 있는 자료'에 대해서만 적용 가능하다. 2. 동작방식 🎓 동작 방식은 다음과 같다. 원소의 최댓값을 포함할 수 있는 배열 설정 각각의 원소가 몇 번 등장하는지 카운팅 count 배열의 인덱스 = 원소 값 count 배열의 값 = 등장 횟수 count 배열을 누적합으로 만들어주기 정렬되지 않은 배열(초기값)의 뒤에서부터 돌면서, 원소의 값과 동일한 인덱스가 가리키는 곳에 원소 배치해 주기 '0 2 1 1 4 4 4 3 5'가 주어졌을 때 동작방식을 아래의 그림을 ..