Language 65

자료 구조 - 레드-블랙 트리(Red-Black Tree)를 왜 사용할까?

레드-블랙 트리(Red-Black Tree)를 왜 사용할까? 레드 블랙 트리(Red-Black Tree)는 어떤 목적을 위해서 사용할까? 알아보자. 먼저 자바의 TreeSet과 TreeMap은 레드-블랙 트리를 베이스로 한 구현을 사용한다. 우리가 트리에 저장하는 절차를 살펴보자. 트리 일반적인 트리 구조에서는 삽입할 데이터 n이 있을 때 부모 노드부터 탐색하면서 삽입한 데이터보다 n이 해당 노드보다 작으면 왼쪽 노드에, 해당 노드보다 크면 오른쪽 노드에 저장한다. 그럼 데이터 1, 2, 4, 8이 저장되면 어떻게 될까? 편향 이진 트리가 된다. 배열로 표현하면 공간도 많이 소모될 뿐 아니라 탐색하는데 시간 복잡도 O(n)이 소모된다. 이러한 현상을 막으려면 중간중간에 재배열을 해서 위와 같이 시간복잡도..

Language/Algorithm 2022.09.30

Java - 배열(Array)을 사용할 때 주의해야 할 점! [+ 공변(Convaiant)]

나는 배열과 리스트의 차이가 '자원 공간이 동적인지의 여부'로 생각해왔다. 그래서 자원 공간이 정해져있는 경우에는 배열을 사용했고, 그렇지 않은 경우에는 리스트를 사용해왔다. 하지만 현재는 생각이 바뀌게 되었다. Array(배열) vs ArrayList(리스트) In Java Array와 ArrayList의 차이점을 간단하게 정리해보자. Array(배열) 사이즈가 정적인 데이터 구조 primitive 타입과 인스턴스 타입 모두 원소로 포함될 수 있다. Generic(제너릭)을 사용할 수 없다. 부수적인 내용 (길이를 구할때는 length 변수를 사용, 할당은 = 를 사용, ...) ArrayList(리스트) 사이즈가 동적인 데이터 구조 인스턴스만 원소로 포함될 수 있다. Generic(제너릭)을 지원한다..

Language/Java 2022.09.07

Java - 리플렉션 사용하기!

리플렉션은 구체적인 클래스 타입을 알지 못해도, 해당 클래스의 메소드나 타입, 변수 들에 접근할 수 있도록 해주는 자바 API이다. 리플렉션은 JVM이 클래스 로더를 통해 읽어온 클래스 정보(reflect된 정보)를 통해 접근한다. 리플렉션은 아래의 경우 사용한다. 특정 애노테이션이 붙어있 필드 또는 메소드를 읽어오기 특정 이름 패턴에 해당하는 메소드 목록 가져와 호출하기 ... 예시 리플렉션을 사용하면 문자열로 클래스를 만들 수 있다. 아래의 코드를 보자. Class HelloClass = Class.forName("jaehoney.blogcode.Hello"); 문자열(package name)를 사용해서 클래스 정보를 꺼내온다. 이후에 해당 클래스의 인스턴스를 만들 수도 있다. Constructor ..

Language/Java 2022.09.04

Effective Java - 추상 클래스와 인터페이스 차이

Java 8부터 인터페이스도 default method를 제공할 수 있게 되었다. 즉, 추상 클래스와 인터페이스 모두 인스턴스 메서드를 구현 형태로 제공할 수 있다. Effective Java에서는 '가능한' 추상클래스가 아닌 인터페이스를 활용하는 것을 권장한다. 그 차이는 무엇인지 알아보자. Abstract Class vs Interface 해당 두 가지 개념의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점이다. 자바는 단일 상속만 지원하니, 추상 클래스 방식은 새로운 타입을 정의하는 데 커다란 제약을 안게 되는 것이다. 반면, 인터페이스를 구현하면 다른 어떤 클래스를 상속했든 같은 타입으로 취급된다. 기존 클래스에도 손쉽게 새로운 ..

Language/Java 2022.09.02

Effective Java - Comparable을 잘 구현하는 방법!

Comparable Java로 알고리즘 공부를 하는 사람이라면 Comparable을 매우 자주 사용하게 된다. Comparable을 구현하면 인스턴스들의 순서를 손쉽게 정할 수 있다. 문제는 Comparable을 구현하는 방법을 잊어먹는 경우가 많다. 이는 Comporable 구현이 어렵기 때문이다. 예시 일반적으로 Comparable을 사용하는 예시를 살펴보자. class Point implements Comparable { int x, y, z; @Override public int compareTo(Point p) { if(this.x > p.x) { return 1; } else if(this.x == p.x) { if(this.y > p.y) { return 1; } else if(this.y ..

Language/Java 2022.09.01

Effective Java - try-finally 대신 try-with-resources 사용하기!

기존의 코드 - try, finally Java 7 버전 이전에는 다 사용하고 난 자원을 반납하기 위해 try-catch-finally 구문을 사용했다. 예시로 살펴보자. public class MainApplication { public static void main(String[] args) { Scanner scanner = null; try { scanner = new Scanner(new File("input.txt")); // scanner 사용 } catch (FileNotFoundException e) { // 예외 처리 } finally { if (scanner != null) { scanner.close(); } } } } 예시에서는 Scanner를 생성하고 finally 구문 안에서 ..

Language/Java 2022.08.31

Effective Java - 빌더 패턴 안전하게 사용하기 (+Use Lombok)

점층적 생성자 패턴 점층적 생성자 패턴은 필수 매개변수만 받는 생성자를 만들고, 선택 매개변수가 더 필요할 때마다 추가로 생성자를 구현하는 방식이다. 점층적 생성자 패턴은 안전하게 객체를 생성할 수 있다는 장점이 있다. public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; public NutritionFacts(int servingSize, int servings, int calories, int fat) { this.servingSize = servingSize..

Language/Java 2022.06.18

DP(Dynamic Programming) - Top-down과 Bottom-up

Top-down / Bottom-up DP(Dynamic Programming) 방식은 크게 두 가지로 나뉜다. Top-down 방식과 Bottom-up 방식이다. 두 방법 모두 큰 문제를 여러 개의 부분 문제들로 나누어 푸는 방식인데 아래의 차이가 있다. - Top-down 방식은 가장 큰 문제를 방문한 후 작은 문제를 호출하여 답을 찾는 방식이다. - Bottom-up 방식은 가장 작은 문제들부터 답을 구해가며 전체 문제의 답을 찾는 방식이다. 일반적으로 Top-down은 재귀 호출을 Bottom-up은 반복문을 이용하여 구현한다. 피보나치 문제의 구현하는 예시를 살펴보자. Top-down 아래는 Top-down 방식의 예시이다. int fibonacci(int n) { if (n == 0) retu..

Language/Algorithm 2022.05.28

Java - 애노테이션(Annotation)이란 무엇인가 ?

애노테이션(Annotation) 자바 개발을 하다 보면 클래스 또는 메서드 또는 변수 앞에 @Override 같은 표시를 많이 본다. Spring처럼 각종 프레임워크나 라이브러리도 애노테이션을 많이 활용한다. 애노테이션은 메타 데이터(데이터에 대한 설명을 하기 위한 데이터)의 역할을 주로 한다. 애노테이션은 내부적으로 어떻게 동작할까? 구현하면 어떤 문제를 해결할 수 있을까? 에 대해 알아보자. Java에서 제공하는 애노테이션 종류 예를 위해 자바에서 제공하는 애노테이션을 살펴보자. 주로 해당 데이터를 설명하기 위해서 사용한다. 1. @Override 선언한 메서드가 오버라이드 되었다는 것을 나타낸다. 상위(부모) 클래스(또는 인터페이스)에서 해당 메서드를 찾을 수 없다면 컴파일 에러를 발생한다. 2. ..

Language/Java 2022.05.21

Java - 제네릭(Generic)타입을 제한하는 방법! (2)

제네릭(Generic) 타입 제한 지난 1장(Java - 제네릭은 무엇인가)에 이어서 제너릭을 사용해서 타입을 제한하거나 와일드카드로 사용하는 방법을 알아본다. 지난 장에서 봤듯 제너릭을 사용하면 타입 체크를 효율적으로 수행할 수 있다. 일반적인 제너릭 형식을 사용한 클래스를 만들었다고 가정하자. 하지만 이 방식으로 클래스를 선언했을 떄 제너릭 타입은 모든 타입을 허용 한다. public class MyClass implements MyInterface{ private E element; void set(E element) { this.element = element; } } 해당 클래스의 인스턴스 객체를 생성할 때 제너릭 타입을 명시한다. MyClass instance = new MyClass(); 여..

Language/Java 2022.05.08