1. 자바의 주요 특징
1.1 객체 지향 프로그래밍
1) 캡슐화
- 속성과 행위를 외부와 분리하는 개념
- 속성을 변수에, 행위를 메소드에, 캡슐을 클래스에 빗댈 수 있다.
- 외부 코드가 데이터에 직접 접근하지 못하도록 방어막 역할을 하고 내부 상태로는 private으로, 외부에는 public 메소드를 노출하여 정보를 은닉(Information Hiding)할 수 있다.
ex) Setter/Getter 메소드를 이용한 캡슐화
- name 변수에 직접 접근하지 않고 반드시 setName() 메소드로 변경을, getName() 메소드로는 조회를 진행하는 방식
public class Encapsulation
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2) 추상화
- 복잡한 시스템에서 핵심적인 개념 또는 기능을 간추려내는 것
- 수행하는 방법이 아니라 수행하는 일 자체에 집중해 복잡도를 낮추는 것
3) 상속
- 한 객체를 또 다른 객체가 이어받는 것
- 유사하게 부모 코드를 자식 코드가 재사용할 수 있다.
4) 다형성
- 경우에 따라 객체가 다르게 동작하거나 또는 어떤 동작을 다른 방법으로 동작하게 하는 개념
- 메소드 오버로딩
-> 이름은 같지만 파라미터가 다른 메소드
- 메소드 오버라이딩
-> 상속을 받아서 메소드를 재정의하는 것
1.2 제네릭
제네릭(Generic)
- 클래스나 메소드에서 사용할 자료형을 컴파일 타임에 미리 지정하는 방식
- 이를 통해 컴파일 시점에 타입 검사를 할 수 있게 되어 객체의 타입 안정성을 높일 수 있으며, 타입 변환 시에도 자동으로 검사를 수행할 수 있다.
ex)
- 제네릭의 등장으로 정확한 타입을 사용했는지 여부를 컴파일 시점에 확인할 수 있게 되었다.
- 자료형을 명확히 선언할 수 있어 가독성이 높아졌다.
List<String> listNames = new ArrayList<String>();
listnames.add("카리나");
listnames.add("윈터");
listnames.add("지젤");
listnames.add("닝닝");
listnames.add(34); //에러 발생
- 제네릭을 사용하여 타입을 명시에 편리하게 반복문 구성
for(String name : listNames)
{
System.out.println(name);
}
1.3 함수형 프로그래밍 언어
- 자바 8버전이 등장하면서 함수형 프로그래밍이 도입되었다.
- 함수형 언어 개념은 코딩 테스트에도 매우 유용하다.
1) 람다 표현식
- 함수형 인터페이스(Functional Interface)를 매우 적은 코딩으로 간결하게 구현할 수 있다.
- 람다 표현식의 기본 문법
(파라미터) -> 내용
- 함수형 인터페이스
-> 추상 메소드를 하나만 갖는 인터페이스
ex)
@FunctionalInterface
interface MathInterface {
double getPiValue();
}
- 이 인터페이스를 활용하려면 기존에는 다음과 같이 익명 클래스(Anonymous Class)를 생성해 메소드명을 기입하고 사용했다.
MathInterface math = new MathInterface() {
@Override
public double getPiValue() {
return 3.141592;
}
};
System.out.println("Pi: " + math.getPiValue());
- 그러나 람다 표현식을 활용하면 다음과 같이 메소드명을 기입하지 않고도 ( )->3.141592 와 같은 하나의 식으로 간단하게 구현할 수 있다.
MathInterface math = () -> 3.141592;
System.out.println("Pi: " + math.getPiValue());
- 이와 같이 람다표현식은 특히 정렬을 구현할 때 유용하다.
ex)
- Member라는 엔티티 클래스가 있고 여기에 다음과 같이 데이터를 삽입했다고 가정
class Member {
String name;
int age;
public Memeber(String name, int age) {
this.name = name;
this.age = age;
}
}
//리스트에 데이터 삽입
List<Member> members = new ArrayList<>();
members.add(new Member("윈터",23));
members.add(new Member("카리나", 24));
members.add(new Member("닝닝", 23));
- 나이를 추출해 역순으로 정렬하는 코드
-> 익명 클래스로 정렬 기준을 구현
//정렬을 익명 클래스로 구현
Collections.sort(members, new Comparator<Member>() {
@Override
public int compare(Member o1, Member o2) {
reutrn o2.age - o1.age;
}
});
- Compartor는 함수형 인터페이스이며 다음과 같이 람다표현식으로 표현 가능
//정렬을 람다 표현식으로 구현
members.sort((o1,o2) -> o2.age - o1.age);
2) 스트림 API
- 번거로운 반복 작업을 단 몇줄의 코드로 간결하게 처리할 수 있게 해주기 때문에 코딩 테스트에서도 매우 유용하다.
ex)
- 나이가 24세인 멤버의 이름을 정렬해 출력
//스트림 API를 사용하지 않는 예전 방식
List<String> chosenMembers = new ArrayList<>();
//나이가 24세인 멤버의 이름을 chosenMembers 리스트에 삽입
for(Member member : members) {
if(member.age == 24)
chosenMembers.add(member.name);
}
//chosenMembers 정렬
Collections.sort(chosenMembers);
//chosenMembers 출력
for(String name : chosenMembers) {
System.out.println(name);
}
- 스트림 API를 이용해 위 코드를 함수형으로 변경
-> 스트림을 시작(stream())한 다음, 나이가 24세인 값을 필터링(filter())하고, 이름 필드를 가져온 후(map()) 정렬(sorted())을 거쳐 마지막 과정으로 리스트로 취합(collect())까지 한 번의 파이프라인으로 처리 가능
//스트림 API 사용방식
members.stream() //스트림 API
.filter(m->m.age == 24) //24세 필터링
.map(m->m.name) //이름 매핑
.sorted() //정렬
.collect(Collections.toList()) //리스트로 취합
.forEach(System.out::println); //메소드 참조로 출력
2. 자바의 도구
JShell
- 자바 9버전에서 등장하면서 REPL 환경을 사용 할 수 있게 되었다.
- REPL (Read-Eval-Print Loop)
-> 입력하고 실행하고 출력하는 과정을 반복하면서 결과를 실시간으로 확인할 수 있는 상호작용 환경
- 터미널에 jshell만 입력하면 간단히 실행
'Java > 알고리즘' 카테고리의 다른 글
[자바 알고리즘 인터뷰] 6장 문자열 처리(3) 로그 파일 재정렬 (0) | 2024.04.04 |
---|---|
[자바 알고리즘 인터뷰] 6장 문자열 처리(2) 문자열 뒤집기 (0) | 2024.04.03 |
[자바 알고리즘 인터뷰] 6장 문자열 처리(1) 유효한 팰린드롬 (0) | 2024.04.03 |
[자바 알고리즘 인터뷰] 5장 빅오 (0) | 2024.04.03 |
[자바 알고리즘 인터뷰] 4장 자료형 (0) | 2024.04.02 |