배운 내용
- 컬렉션(List, Set, Map)
- 제너릭
- 와일드카드
교육 회고
5주차를 맞이 하였다.
새 해가 되었고 나는 새 해 첫날부터 감기몸살에 시달렸다.
정신연령이야 어쨌던, 한 살 두 살 나이를 먹어가다보니 과연 회복력이...
12월 31일 저녁부터 시름시름 앓기 시작했는데, 1월 1일과 1월 2일엔 침대에서 일어나기도 힘들었고
1월 3일엔 괜히 수업에 나갔다가 제대로 수업도 못듣고 종일 엎드려만 있었다.
3일 저녁부턴 몸살에 항생제의 부작용으로 추정되지만 아무튼 장염끼까지 겹쳐서 최악의 날을 보냈다.
4일에도 수업을 못듣고 5일 오후나 되서야 조금 살 만 해졌다.
무려 5일이나 아팠는데... 과거에는 이렇게 길게 아팠던 적이 없었다...
5주차에는 수업을 하루밖에 안들은 셈이라, 뭘 배웠는지 가늠하기 힘들다.
컬렉션, 제너릭에 대해서 배운 모양이지만 나는 별로 들은 내용이 없긴 했다.
그럼에도 불구하고 조금 독학과 조금 들은 수업 내용을 곁들여 정리를 해볼까 한다.
컬렉션
데이터를 효율적으로 저장하고 관리하는 자료 구조를 제공하는 패키지.
배열보다 더 다양한 기능과 유연성을 지니고 있다...
주요 컬렉션 클래스들은 java.util 안에 함께 있다.
대표적인 주요인터페이스와 구현 클래스
List, Set, Map:
List
순서가 있는 데이터의 집합.
중복을 허용.
예시: ArrayList, Vector, LinkedList.
// List 생성
List<String> names = new ArrayList<>();
// 데이터 추가
names.add("Alice");
names.add("Bob");
names.add("Charlie");
// 데이터 접근
System.out.println(names.get(0)); // Alice
// 데이터 삭제
names.remove("Bob");
// 리스트 크기 확인
System.out.println(names.size()); // 2
Set (집합)
순서가 없는 데이터의 집합.
중복을 허용하지 않음.
예시: HashSe TreeSet, LinkedHashSet.
// Set 생성
Set<Integer> numbers = new HashSet<>();
// 데이터 추가
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(1); // 중복 데이터는 허용되지 않음
// 데이터 확인
System.out.println(numbers); // [1, 2, 3]
Map (맵)
Key-Value 쌍으로 데이터를 저장.
Key는 중복되지 않음.
예시: HashMap, HashTable, TreeMap, Properties.
// Map 생성
Map<String, Integer> ages = new HashMap<>();
// 데이터 추가
ages.put("Alice", 25);
ages.put("Bob", 30);
ages.put("Charlie", 22);
// 데이터 접근
System.out.println(ages.get("Bob")); // 30
// 데이터 삭제
ages.remove("Alice");
// 맵에 특정 Key가 있는지 확인
System.out.println(ages.containsKey("Alice")); // false
일단 이정도.
이해했다.
그나마 List는 로또프로그램 리팩토링할때 사용해봐서 친근하게 느껴진다...
데이터객체(VO) - Student, Board
데이터처리객체(Dao) - BoardDao -> List list = new ArrayList();
원하는 객체를 불러서 프로그램 시작 객체 BoardExample, StudentMain)
자바 컬렉션 프레임워크
자료구조를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색 할 수 있도록 관련된 인터페이스와 클래스를 java.util 패키지에서 제공한다.
주요인터페이스
List, Set, Map
List, Set은 객체를 추가, 삭제, 검색 방법의 공통점이 있기 때문에 공통된 메소드를 따로 모아서 Collection 인터페이스로 정의하고 이를 상속하고 있다.
Map은 키와 값을 하나의 쌍으로 묶어서 관리하는 구조...
- List컬렉션
객체를 인덱스로 관리한다.
객체를 저장하면 인덱스가 부여되고, 인덱스로 검색/삭제 기능 제공한다
... - .
.
.
.
제너릭
자바프로그래밍 언어의 타입 안정성 강화를 위해 JAVA5부터 도입된 기능이다.
제너릭을 사용하면 타입을 매개변수화 할 수 있다.
동일한 코드를 다른 타입에 사용할 수 있다.
- 제너릭 타입 매개변수
-클래스
-인터페이스
-메서드
를 정의할 수 있는 기능을 제공한다. 컴파일 시 실제 타입으로 대체되어 타입 안정성을 보장한다. - 제너릭 클래스
하나 이상의 타입 매개변수가 있는 클래스
class MyGenericClass<T>{brabra} // T -> 타입 매개변수
제너릭 클래스의 객체 생성타입 매개변수 Integer를 사용하여 MyGenericClass의 객체를 생성한다.
obj의 사용이 Integer객체만 받도록 제한된다.
MYGenericClass<Integer> obj = new MyGenericClass<Integer>(); - 제너릭 메소드
자체 타입 매개변수를 갖는 메소드
클래스 수준 타입의 매개변수와 다른 자체 타입 매개변수를 가질 수 있다.타입 매개변수 T가 있는 제너릭 메소드 MyGenericMethod를 정의한다.
public <T>void MyGenericMethod(T param1, Tparam2 ...){...} - 제너릭의 와일드 카드 (%)
와일드 카드 : 유연성을 제공하고 알 수 없거나 여러 타입을 사용 할 수 있도록 지원.
-상한 와일드 카드<?>
지정된 상한 또는 하위 타입을 사용할 수 있도록 허용. 특정 타입이 중요하지 않은 객체 컬렉션을 작업할 때 유용하다.
-하한 와일드 카드<? extends T> <? super T>
지정된 하한 클래스와 동일하거나 상위 타입의 모든 타입을 사용할 수 있다. - 타입 삭제
타입 지우기 기능 지원.
제너릭 필요성
다양한 타입의 데이터에서 작동할 수 있는 재사용 가능한 코드를 만드는데 유용하다
클래스와 메소드를 만들 수 있다
호환되지않은 타입의 사용을 방지할 수 있다 (오류가능성을 줄인다 이거지)
-코드 중복 최소화
-코드 베이스를 유지/관리 편해진다
-컴파일 시 타입 안정성을 제공하여 런타임 오류의 가능성을 줄일 수 있다.
타입매개변수란? (자리표시자) 대문자로 표시하는것이 룰.
문제1)
서로 다른 두 가지 타입의 객체를 타입 매개변수로 취하는
"Pair" 제너릭 클래스를 생성하세요.
쌍의 첫번째와 두번째 객체를 나타내는 타입T와 U의 개인 인스턴스 변수
두 개가 있어야 한다.
이 인스턴스 변수를 초기화 하는 생성자와 인스턴스 변수의 값을 검색하는
getter메소드가 있어야 한다.
public class Pair<T, U>{
private T t;
private U u;
public Pair(T t, U u) {
this.t = t;
this.u = u;
}
public T getT() {
return t;
}
public U getU() {
return u;
}
}
문제2)
'MyClass'클래스에 모든 타입의 배열을 매개변수로 받아 배열의 요소를 출력하는
printArray 제너릭 메소드를 작성해주세요.
public class MyClass <T>{
public static <T>void printArray(T[] array){
for (T element : array){
System.out.println(element);
}
}
}
문제3)
모든 타입의 두 객체를 매개변수로 받고 비교를 나타내는 정수 값을 반환하는
"compare" 단일 메소드를 사용하여 Comparator라는 제너릭 인터페이스를 만드세요.
public interface Comparator <T>{
public int compare(T o1, T o2);
}
문제4)
모든 타입의 객체를 담을 수 있는 Box라는 제너릭 클래스를 생성하세요
객체는 items라는 ArrayList에 저장됩니다.
상자에 (Box)객체를 추가(addItem())하고, 상자에서 객체를 검색(getItem)하고,
상자가 비어있는지 확인하는 메소드(isEmpty)를 구현
public class Box <T>{
private List<T> items;
public Box() { //생성자에서 저장공간을 만들어준다.
this.items = new ArrayList<>();
}
public void addItem(T item){
items.add(item);
}
public T getItem(){
if (!items.isEmpty()){
return items.get(0);
}
return null;
}
public boolean isEmpty(){
return items.isEmpty();
}
}
- 제너릭
다양한 타입에서 재사용할 수 있는 제너릭 코드를 제공.
타입캐스팅이 필요없다.
자바 프로그래밍에서 필수적이다...
//문제5)
//MyClass2
//배열과 두개의 인덱스를 받아, 주어진 인덱스에서 요소를 교환하는
//static void swap 제너릭 메소드를 구현하세요.
//swap 메소드는 모든 타입의 배열을 처리할 수 있어야 한다.
public class MyClass2 {
public static <T> void swap(T[] array, int i1, int i2) {
T temp;
temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4, 5};
System.out.println("------before swap------");
for (Integer number : intArray) {
System.out.println(number);
}
System.out.println("------after swap------");
swap(intArray, 1, 3);
for (Integer number : intArray){
System.out.println(number);
}
}
}
.
.
//문제6)
//모든 타입의 요소 두개를 저장하고, 요소를 교환하는 메소드 swap를 구현하세요.
//문제 1번 Pair 제너릭 클래스에 추가합니다.
public class Pair2<T>{
private T first;
private T second;
public Pair2(T first, T second) {
this.first = first;
this.second = second;
}
public void swap(){
T temp = first;
first = second;
second = temp;
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
public static void main(String[] args) {
Pair2<Integer> intPair = new Pair2(1,2);
System.out.println(intPair.getFirst());
}
}
.
.
//문제7)
//MyGnericClass3
//배열과 요소를 받아 배열 내에서 해당 요소의 발생 횟수를 반환하는
//countOccurrences 제너릭 메소드를 구현하세요
public class MyClass3 {
public static <T> int countOccurrences(T[] array, T element){
int count = 0;
for (T item : array){
if (item.equals(element)) count++;
}
return count;
}
public static void main(String[] args) {
String[] strArray = {"apple", "banana", "apple", "orange", "apple"};
String target = "apple";
int occurrences = countOccurrences(strArray, target);
System.out.println(target + " : " + occurrences);
}
}
와일드카드
자바 제너릭에서 알 수 없는 타입을 나타낼 때 사용한다.
와일드카드를 사용하면 제너릭 타입 매개변수를 다른 타입으로 대체할 수 있도록 지정이 가능하다.
- 필요성
매개변수의 정확한 타입을 알 수 없거나, 관련이 없는 상황에서 타입안정성을 희생하지 않고 알 수 없는 타입을 처리할 수 있는 방법을 제공한다. - 자바 제너릭 와일드카드는 물음표로 표시한다.<?>
-바인딩되지 않은 와일드 카드('?') : 알 수 없는 타입을 나타낸다. 실제 타입 인수에 관심이 없는 상황에서 사용할 수 있다.
: 상황1) 알 수 없는 요소의 리스트를 받아 문자열 표현을 출력해야하는 메소드 구현
-상한 바운드 와일드카드 (? extends Type)public static void printList(List<?> list){ for(Object element : list){ System.out.println(element.toString()); } }
- 지정된 타입의 하위 타입인 알 수 없는 타입을 나타낸다. 특정 클래스나 인터페이스에서 파생된 모든 타입 허용..
상황2) 숫자 리스트의 합계를 계산하는 listTotal()
-하한 와일드카드 (? super Type)public static Double listTotal(list<? extends Number> numbers){ double total = 0; for(Number number : numbers){ total += number.doubleValue(); } return total; }
- 지정된 타입의 상위 타입인 알 수 없는 타입을 나타낸다. 특정 클래스나 인터페이스의 상위 타입인 모든 타입을 허용하려는데 유용하다.
? super Integer 사용하면 addElements() 메소드가 Object 또는 Number와 같은 Integer의 모든 상위 타입인 List 허용할 수 있다.public static void addElements(List<? super Integer>list){ list.add(10);}
정수와 Integer의 상위타입인 다른 모든 객체를 추가할 수 있다.
- 지정된 타입의 하위 타입인 알 수 없는 타입을 나타낸다. 특정 클래스나 인터페이스에서 파생된 모든 타입 허용..
문제8)
모든 타입의 ArrayList를 출력할 수 있는 printList라는 메소드를 작성하세요. 단, 와일드 카드를 사용하세요.)public class WildCardEx { public static void printList(List<?>list){ for (Object element : list){ System.out.println(element); } }
public static void main(String[] args) {
List<Integer> numberList = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10));
List<String> stringList = new ArrayList<>(List.of("lee", "kim", "jin"));
printList(numberList);
printList(stringList);
Board board1 = new Board(1,"소설","반지의 제왕", "톨킨");
Board board2 = new Board(1,"소설","반지의 제왕", "톨킨");
Board board3 = new Board(1,"소설","반지의 제왕", "톨킨");
List<Board> BoardList = new ArrayList<>(List.of(board1, board2, board3));
printList(BoardList);
}
문제9)
객체 리스트를 받아들이고, 리스트의 각 요소를 출력하는 printList 메소드를 만들었다.
이 메소드는 Comparable 인터페이스를 구현하는
객체 리스트만 받아서 printList 할 수 있도록 수정해라.
```java
public class WildCardEx {
public static <T extends Comparable<T>& Cloneable>void printList(List<?>list){
//이 메소드는 Comparable 인터페이스를 구현하는
//객체 리스트만 받아서 printList 할 수 있다
for (Object element : list){
System.out.println(element);
}
}
public static void main(String[] args) {
List<Integer> numberList = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10));
List<String> stringList = new ArrayList<>(List.of("lee", "kim", "jin"));
printList(numberList);
printList(stringList);
Board board1 = new Board(1,"소설","반지의 제왕1", "톨킨");
Board board2 = new Board(2,"소설","반지의 제왕2", "톨킨");
Board board3 = new Board(3,"소설","반지의 제왕3", "톨킨");
List<Board> BoardList = new ArrayList<>(List.of(board1, board2, board3));
printList(BoardList);
}
}
'개발 공부 회고(23.12 - ) > SSG Java 백엔드 과정(23.12 - 24.06)' 카테고리의 다른 글
SSG 7주차 회고 - 데이터베이스, MySQL (0) | 2024.01.18 |
---|---|
SSG 6주차 회고 - 람다식, 스트림, 스레드 (1) | 2024.01.13 |
SSG 4주차 회고 - 객체지향, 예외, 깃허브 (0) | 2024.01.07 |
SSG 3주차 회고 - 객체지향, 상속, 추상클래스, 인터페이스, 모델링 (1) | 2024.01.07 |
SSG 2주차 회고 - 배열, 문자열 (0) | 2024.01.07 |