Backend
home

2024. 7. 23

참고링크

개발자 로드맵 링크 : roadmap.sh

Map 컬렉션 - Hashtable

Hashtable 은 HashMap과 동일한 내부 구조를 가지고 있으며, 동기화된 메소드로 구성되어 있어서 멀티 스레드가 동시에 Hashtable 메소드를 실행할 수 없다는 점에서 차이가 있다.
즉, 멀티 스레드 환경에서도 안전하게 객체를 추가, 삭제할 수 있다.

Map 컬렉션 - Properties

Properties는 Hashtable의 자식 클래스이기 때문에 Hashtable의 특징을 그대로 가지고 있다.
Properties는 키와 값을 String 타입으로 제한한 컬렉션으로, 확장자가 .properties인 프로퍼티 파일을 읽을 때 사용한다.
Properties properties = new Properties(); properties.load(xxx.class.getResourceAsStream("파일명.properties"));
Java
복사

TreeMap

이진 트리 기반으로 검색 기능을 강화한 Map 컬렉션이다.
TreeSet과의 차이점은 키와 값이 저장된 Entry를 저장한다.
TreeMap에 저장되는 객체는 저장과 동시에 오름차순으로 정렬된다. (키를 기준으로 낮은 것은 왼쪽 자식 노드에, 높은 것은 오른쪽 자식 노드에 저장)
Comparable 인터페이스를 구현하고 있는 객체만이 정렬 가능하다.
TreeMap<K, V> treeMap = new TreeMap<K, V>(); TreeMap<K, V> treeMap = new TreeMap<>();
Java
복사

컬렉션 자료구조 - Comparable과 Comparator

TreeSet에 저장되는 객체와 TreeMap에 저장되는 키 객체는 저장과 동시에 오름차순으로 정렬된다.
어떤 객체든 정렬될 수 있는 것은 아니고 객체가 Comparable 인터페이스를 구현하고 있어야 가능하다.
Integer, Double, String 타입은 모두 Comparable을 구현하고 있기 때문에 상관 없지만, 사용자가 직접 정의한 객체를 저장할 때에는 반드시 Comparable을 구현하고 있어야 한다.
Comparable 인터페이스에는 compareTo() 메소드가 정의되어 있다. 따라서 사용자 정의 클래스에서 이 메소드를 재정의해서 비교 결과를 정수값으로 반환해야 한다.
Comparator는 함수형 인터페이스다. (추상 메소드 한 개있는 것을 함수형 인터페이스라고 함)
package com.collection.map; import lombok.AllArgsConstructor; import lombok.Data; @AllArgsConstructor @Data public class Book implements Comparable<Book> { private String title, isbn; private int year; @Override public int compareTo(Book o) { // return this.title.compareTo(o.getTitle()); // 제목 글자수 오름차순 정렬 Integer thisTitleLength = this.title.length(); Integer otherTitleLength = o.title.length(); return thisTitleLength.compareTo(otherTitleLength); } } //=========================================================================== package com.collection.map; import java.util.TreeSet; public class SortExample { public static void main(String[] args) { TreeSet<Book> bookSet = new TreeSet<>(); bookSet.add(new Book("개를 훔치는 완벽한 방법", "B1", 2002)); bookSet.add(new Book("수상한 장미마을", "B2", 2000)); bookSet.add(new Book("위대한 개츠비", "B3", 1980)); bookSet.add(new Book("언어의 온도", "B4", 2015)); bookSet.add(new Book("아몬드", "B5", 2006)); System.out.println(bookSet); } }
Java
복사

컬렉션 자료구조 - LIFO와 FIFO 컬렉션

후입선출(LIFO: Last In First Out)은 나중에 넣은 객체가 먼저 빠져나간다.
선입선출(FIFO: First In First Out)은 먼저 넣은 객체가 먼저 빠져나가는 구조를 말한다.
컬렉션 프레임워크는 LIFO 자료구조를 제공하는 스택(Stack)클래스와 FIFO 자료구조를 제공하는 큐(Queue) 인터페이스를 제공한다.
Stack<E> stack = new Stack<E>(); Stack<E> stack = new Stack<>();
Java
복사
Queue 인터페이스는 FIFO 자료구조에서 사용되는 메소드를 정의한다.
Queue 인터페이스를 구현한 대표적인 클래스는 LinkedList이다. 따라서 LinkedList 객체는 Queue 인터페이스 변수에 아래와 같이 대입할 수 있다.
Queue<E> queue = new LinkedList<E>(); Queue<E> queue = new LinkedList<>();
Java
복사

동기화된 컬렉션

여러 스레드가 동시에 컬렉션에 접근하면 의도하지 않게 요소가 변경될 수 있다.
Vector와 HashTable은 동기화된(Synchronized) 메소드로 구성되어 있기 때문에 멀티 스레드 환경에서 안전하게 요소를 처리할 수 있지만, 다른 자료구조들은 동기화된 메소드로 구성되어 있지 않아 멀티 스레드 환경에서 안전하지 않다.
만약 멀티 스레드 환경에서 사용하고자 한다면, 비동기화된 메소드를 동기화된 메소드로 래핑하는 Collections의 synchronizedxxx() 메소드를 사용하면 된다.

수정할 수 없는 컬렉션

요소를 추가, 삭제할 수 없는 컬렉션은 수정할 수 없는 컬렉션이라 한다.
컬렉션 생성시 저장된 요소를 변경하고 싶지 않을 때 사용할 수 있다.
수정할 수 없는 컬렉션 만드는 방법
List, Set, Map 인터페이스의 정적 메소드인 of() 로 생성
List<E> immutableList = List.of(E element1,); Set<E> immutableSet = Set.of(E element2,); Map<E> immutableMap = Map.of(K k1, V v1,);
Java
복사
List, Set, Map 인터페이스의 정적 메소드인 copyOf( )로 생성
List<E> immutableList = List.copyOf(Collection<E> coll); Set<E> immutableSet = Set.copyOf(Collection<E> coll); Map<E> immutableMap = Map.copyOf(Map<K, V> map);
Java
복사
배열로부터 수정할 수 없는 List 컬렉션 생성
String arr = {}; List<String> immutableList = Arrays.asList(arr);
Java
복사

람다식

메서드를 “하나의 식” 으로 표현한 것이다.
메서드의 이름과 반환값이 없어지므로 “익명함수” 라고도 한다.
함수형 프로그래밍:
함수를 정의하고, 해당 함수를 데이터 처리부로 보내 데이터를 처리하는 기법. 데이터 처리부에서 데이터만 가지고 있을 뿐, 데이터 처리 방법이 정해져 있기에 외부에서 제공된 함수에 의존한다. ⇒ 추상 메소드를 정의하고, 추상 메소드를 오버라이딩된 곳으로 보내서 처리하도록 시킨다. 추상 메소드 쪽에서는 데이터만 가지고 있으며 처리 방법은 정해져 있지 않다.
람다식은 데이터 처리부에 제공되는 함수 역할을 하는 매개변수를 가진 중괄호 블록으로, 익명 구현 객체로 변환하여 동작한다.
익명 구현 객체를 람다식으로 표현하기 위해서는 인터페이스가 단 하나의 추상 메소드만을 가지고 있어야 한다.
단 하나의 추상 메소드를 가지고 있는 인터페이스를 함수형 인터페이스라고 부른다. @FunctionalInterface 어노테이션을 붙인다.
람다식에서 매개변수가 하나인 경우에는 소괄호 생략이 가능하고, 실행문이 한 줄인 경우 중괄호 생략이 가능하다.
package com.review; public class CarExample { public static void main(String[] args) { Driver inkyu = new Driver(); inkyu.drive(new K5()); inkyu.drive(new Tesla()); inkyu.drive(new Car() { @Override public void run() { System.out.println("모르는 차인데도 운전이 된다."); } }); inkyu.drive(() -> System.out.println("이름 없는 슈퍼카 부릉부릉")); } }
Java
복사
package com.lambda; public class LambdaExample { public static void main(String[] args) { MyInterface mi = new MyInterface() { @Override public void action(int x) { System.out.println("숫자 " + x + "을 활용한 동작"); } }; mi.action(3); // 같은 동작 MyInterface li = (x) -> System.out.println("숫자 " + x + "을 활용한 동작"); li.action(3); // 같은 동작 } }
Java
복사

인터페이스, 람다식에 대한 이해를 위해

역할, 구현
자동차 역할: 움직이는 역할
운전자 역할: 자동차를 움직인다.

람다식 실행

람다식 실행 방법
함수형 인터페이스의 추상 메소드에 리턴값이 있을 경우, 람다식은 아래와 같이 작성 가능하다.
return문 하나만 존재하는 경우에는 중괄호와 함께 return 키워드를 생략할 수 있다.

람다식 - 메소드 참조

메소드 참조(Method Reference)는 자바 8에서 도입된 기능으로, 기존 메소드나 생성자를 참조하여 람다 표현식을 단축할 수 있다. 이를 통해 코드의 가독성을 향상시키고, 불필요한 매개변수를 제거할 수 있다.
람다식은 매개변수를 받아 값을 전달하는 역할을 할 수 있지만, 메소드 참조를 이용하면 불필요한 매개변수를 제외하고 더 간결하게 작성할 수 있다.
예제
package com.lambda5; @FunctionalInterface public interface Calculable { double calc(double x, double y); }
Java
복사
package com.lambda5; public class Person { public void action(Calculable c) { double result = c.calc(10, 4); System.out.println("결과 : " + result); } }
Java
복사
package com.lambda5; // 서비스 로직만 따로 구현 public class CalculateService { public static double sum(double x, double y) { return x + y; } public static double multiply(double x, double y) { return x * y; } }
Java
복사
package com.lambda5; public class MethodReferenceExample { public static void main(String[] args) { Person p = new Person(); // p.action(인터페이스); -> 인터페이스의 메소드 calc(10, 4) 호출 -> 그 결과 출력 // 추상 메소드 [double calc(double x, double y)] p.action((x, y) -> CalculateService.sum(x, y)); p.action(CalculateService::sum); // 위 코드와 동작 같음 p.action((x, y) -> CalculateService.multiply(x, y)); p.action(CalculateService::multiply); // 위 코드와 동작 같음 } }
Java
복사