형변환
명시적 형변환
int i = 300;
byte b = (byte) i; // 값 손실 발생
묵시적 형변환
byte b = 10;
int i = b; // 값 손실 없음
배열 선언
1차원 배열
int points[] = new int[3];
2차원 배열
int[][] intArray = new int[4][];
문자열을 문자 배열로 변환
String a = new String("123");
char[] charArray = a.toCharArray();
UML
- private: 빨간색
- protected: 노란색
- public: 녹색
- default: 파란색
객체지향 프로그래밍
특징
- 추상화
- 다형성
- 상속
- 데이터 은닉과 보호
객체와 클래스
- 객체: 클래스를 데이터 타입으로 메모리에 생성되어 실제로 동작하는 것
- 클래스: 객체를 정의해 놓은 것
생성자
Person person = new Person();
Person person = new Person("name");
this 키워드
- 객체 자신을 가리킴
- 로컬 변수와 멤버 변수를 구분할 때 사용
public Person(String name) {
this.name = name;
}
public Person() {
this("name");
}
상속
public class Child extends Parents
단일 상속
- 자바는 단일 상속만 지원 (다이아몬드 상속 문제 방지)
오버라이딩
public class Person {
void kick() {
// 차다.
}
}
public class Player extends Person {
@Override
void kick() {
// 공을 차다
}
}
조건
- 메서드 이름, 매개변수, 리턴 타입 동일
- 접근 제한자는 부모와 같거나 더 넓어야 함
- 부모보다 더 큰 예외는 던질 수 없음
접근 제한자
- public: 모든 클래스에서 접근 가능
- protected: 동일 패키지 또는 상속 관계의 클래스에서 접근 가능
- private: 동일 클래스 내에서만 접근 가능 (캡슐화)
- default: 동일 패키지 내의 클래스에서만 접근 가능
Singleton 패턴
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
다형성
- 하나의 객체가 여러 형태를 가질 수 있는 성질
public void println(Object o) {}
public void println(Person p) {}
제네릭
정의
- 다양한 타입의 객체를 다루는 메서드, 컬렉션 클래스에서 컴파일 시 타입 체크
public interface Interface_name<T> {}
형인자
주의할 점
- 프라이미티브 타입 사용 불가
- 타입 캐스팅 시 런타임에 타입 정보 유지되지 않음
- 정적 컨텍스트에서 제네릭 사용 불가
- 제네릭 배열 생성 불가
- 제네릭 타입 인스턴스 생성 불가
자바의 와일드카드 자료형
와일드카드(Wildcard): 불특정 타입을 나타내기 위해 사용 (?
)
- 무제한 와일드카드 (
?
): 어떤 타입이라도 허용
- 상한 경계 와일드카드 (
? extends T
): 특정 타입이나 그 하위 타입을 허용 (읽기 전용)
- 하한 경계 와일드카드 (
? super T
): 특정 타입이나 그 상위 타입을 허용 (쓰기 전용)
Collection 프레임워크
컬렉션(Collection): 여러 개의 객체를 모아서 관리하는 자바의 프레임워크
주요 인터페이스
- Collection: 컬렉션의 기본 인터페이스
- List: 순서가 있는 컬렉션, 중복 허용 (ArrayList, LinkedList)
- Set: 순서가 없는 컬렉션, 중복 불가 (HashSet, TreeSet)
- Queue: FIFO 방식의 컬렉션 (LinkedList, PriorityQueue)
- Map<K, V>: 키-값 쌍으로 이루어진 컬렉션 (HashMap, TreeMap)
주요 구현 클래스
- ArrayList: 가변 크기 배열, 빠른 인덱스 접근
- LinkedList: 이중 연결 리스트, 빠른 삽입/삭제
- HashSet: 해시 테이블, 중복 불가
- TreeSet: 이진 검색 트리, 정렬된 순서 유지
- HashMap: 해시 테이블, 키 중복 불가, 값 중복 가능
정렬 (Sort)
자바에서 배열이나 컬렉션을 정렬하는 방법
1. 배열 정렬
Arrays.sort() 메서드
- 기본형 배열 정렬
int[] numbers = {5, 3, 8, 1, 2};
Arrays.sort(numbers);
- 객체 배열 정렬
String[] names = {"John", "Alice", "Bob"};
Arrays.sort(names);
- Comparator를 사용한 정렬
Arrays.sort(names, (s1, s2) -> s2.compareTo(s1));
2. 컬렉션 정렬
Collections.sort() 메서드
- List 정렬
List<Integer> numberList = Arrays.asList(5, 3, 8, 1, 2);
Collections.sort(numberList);
- 객체 List 정렬 (Comparable 사용)
public class Person implements Comparable<Person> {
private String name;
private int age;
@Override
public int compareTo(Person other) {
return this.age - other.age;
}
}
List<Person> people = Arrays.asList(new Person("John", 25), new Person("Alice", 30));
Collections.sort(people);
- Comparator를 사용한 정렬
Collections.sort(people, (p1, p2) -> p1.name.compareTo(p2.name));
3. 스트림을 사용한 정렬 (Java 8 이상)
- 기본 정렬
List<Integer> numberList = Arrays.asList(5, 3, 8, 1, 2);
List<Integer> sortedList = numberList.stream().sorted().collect(Collectors.toList());
- Comparator를 사용한 정렬
List<Person> sortedPeople = people.stream()
.sorted(Comparator.comparing(Person::getName))
.collect(Collectors.toList());
람다 표현식 (Lambda Expressions)
람다 표현식: 익명 함수를 간결하게 표현하는 방법
문법
(parameters) -> expression
(parameters) -> { statements; }
람다식 정렬
List<String> list = Arrays.asList("B", "A", "C");
Collections.sort(list, (s1, s2) -> s1.compareTo(s2));
List<Person> people = Arrays.asList(new Person("John"), new Person("Alice"));
Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));
스트림 (Stream)
스트림(Stream): 컬렉션을 처리하는 함수형 프로그래밍 API
주요 특징
- 연속된 요소: 컬렉션의 요소를 하나씩 처리
- 함수형 스타일: 선언적이고 함수형 프로그래밍 스타일
- 지연 연산: 최종 연산 시에만 중간 연산 수행
- 무상태 연산: 각 요소를 독립적으로 처리
스트림 원리
- 파이프라인: 소스 -> 중간 연산 -> 최종 연산
- 중간 연산: 지연 연산, 최종 연산 시 수행
스트림 연산 예시
- 스트림 생성
List<String> names = Arrays.asList("John", "Alice", "Bob");
Stream<String> stream = names.stream();
- 중간 연산 (필터링, 변환, 정렬)
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
- 최종 연산 (반복, 집계)
names.stream().forEach(name -> System.out.println(name));
long count = names.stream().filter(name -> name.startsWith("A")).count();
---
### 예외처리 (Exception Handling)
**예외처리**: 예외 상황을 처리하여 프로그램의 비정상 종료를 방지
### 주요 개념과 키워드
1. **try 블록**
- 예외가 발생할 가능성이 있는 코드 포함
```java
try {
// 예외 발생 가능 코드
}
- catch 블록
- finally 블록
- throw 키워드
- throws 키워드
예외 계층 구조
- Checked Exception: 컴파일 시점에서 반드시 처리해야 하는 예외 (
IOException
, SQLException
)
- Unchecked Exception: 런타임 시점에서 발생하는 예외 (
NullPointerException
, ArrayIndexOutOfBoundsException
)
파일 입출력 (File I/O)
파일 입출력: 파일을 읽고 쓰는 작업
주요 클래스 및 인터페이스
- java.io 패키지
- File: 파일 및 디렉토리 경로명 표현
- FileReader: 파일을 문자 스트림으로 읽음
- FileWriter: 파일을 문자 스트림으로 씀
- BufferedReader: 문자 입력 스트림을 버퍼링하여 효율적으로 읽음
- BufferedWriter: 문자 출력 스트림을 버퍼링하여 효율적으로 씀
- FileInputStream: 파일을 바이트 스트림으로 읽음
- FileOutputStream: 파일을 바이트 스트림으로 씀
기본적인 파일 읽기 및 쓰기 예제
문자 스트림
- 파일 쓰기 (FileWriter)
try (FileWriter writer = new FileWriter("example.txt")) {
writer.write("Hello, world!");
} catch (IOException e) {
e.printStackTrace();
}
- 파일 읽기 (FileReader)
try (FileReader reader = new FileReader("example.txt")) {
int data;
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
바이트 스트림
- 파일 쓰기 (FileOutputStream)
try (FileOutputStream output = new FileOutputStream("example.bin")) {
output.write("Hello, world!".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
- 파일 읽기 (FileInputStream)
try (FileInputStream input = new FileInputStream("example.bin")) {
int data;
while ((data = input.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
컴파일 에러
int i;
System.out.println(i); // 초기화 안한 컴파일 오류
런타임 에러
String s = null;
System.out.println(s.length()); // NullPointerException
Teacher t = (Teacher) person; // ClassCastException
Call By Value
String s = new String("hello");
s.concat("world");
System.out.println(s); // hello
s = s.concat("world");
System.out.println(s); // helloworld
인터페이스 VS 추상클래스
|
인터페이스 |
추상클래스 |
공통점 |
추상화: 구체적인 구현 없이 메서드 선언만 포함 가능 |
다형성 지원: 여러 클래스가 공통된 인터페이스나 추상 클래스를 구현함으로써 동일한 타입으로 다룰 수 있음 |
상속 가능 |
차이점 |
구현된 메서드 포함 가능, 필드 가질 수 있음, 생성자 포함 |
구현 포함 안함 (default 메서드는 예외), 필드 가질 수 없음 |
단일 상속 |
다중 상속 |
extends |
implements |
공통된 기능을 공유하면서 일부 메서드의 구체적인 구현을 제공하기 위해 사용 |
클래스 간의 계약을 정의하고, 클래스가 반드시 구현해야 하는 메서드를 명시하기 위해 사용 |
List vs Set vs Map
List
- 입력 순서가 있는 데이터의 집합
- 순서가 있으므로 데이터 중복 허용
- 구현 클래스: ArrayList, LinkedList
Set
- 입력 순서를 유지하지 않는 데이터의 집합
- 순서가 없으므로 데이터를 구별할 수 없음
- 중복 불가
- 구현 클래스: HashSet, TreeSet
Map
- Key, Value의 쌍으로 데이터를 관리하는 집합
- 순서는 없고 Key의 중복 불가, Value 중복 가능
- 구현 클래스: HashMap, TreeMap