특수 클래스 : 내부클래스
- 내부클래스 : 클래스 in 클래스 (클래스 안에 선언한 클래스)
- class Outer {class Inner {}}
- 내부 클래스에서 외부클래스의 유효범위안에 들어가기 때문에 인스턴스 생성없이도(Parameter로써 전달이 되지 않아도) 외부 클래스 인스턴스 멤버에 접근가능하나, 외부에서는 내부 클래스에 접근 불가함.
- 내부클래스가 외부클래스 '안에서만' 사용되는 클래스이기에, 굳이 바깥에 분리하여 둘필요가 없어 외부클래스의 멤버처럼 내부클래스를 캡슐화를 진행하는 개념이다.
- ex) Outerclass.Innerclass var = new Outer().new Innter()
- 원래 클래스에는 default와 public 밖에 사용되지 않는데, 내부클래스는 모든 접근제어자를 사용가능.
내부클래스의 종류
- 인스턴스 클래스 (instance class) : 외부 클래스의 인스턴스에 종속적인 내부 클래스입니다. 이러한 클래스는 외부 클래스의 인스턴스가 생성된 후에야 인스턴스화 될 수 있으며, 외부 클래스의 인스턴스 변수 및 메소드에 직접적으로 접근할 수 있는 권한을 가집니다. 주로 외부클래스 인스턴스의 필드멤버처럼 다루어지며, 인스턴스멤버들과의 작업을 위해 만들어짐.
- 정적 클래스 (static class) : 외부 클래스의 인스턴스 생성과 관계없이 인스턴스를 생성할 수 있는 내부 클래스입니다. 정적 내부 클래스는 외부 클래스의 정적 멤버에 접근할 수 있습니다. ]
- 보통 특정 클래스내에서만 사용될 인스턴스는 중첩정적클래스로 사용한다.
public class InnerRunnableMainV1 {
public static void main(String[] args) {
log("main() start");
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
log("main() end");
}
static class MyRunnable implements Runnable{
@Override
public void run() {
log( "run()");
}
}
- ✓ 지역 클래스 (local class) : 클래스의 메소드 안에 클래스가 있는 경우이며 선언된 내부에서만 사용가능하다.
- ✓ 익명 클래스 (anonymous class) : 부모로부터 상속받을 클래스의 선언과 인스턴스 생성이 동시에 되는 이름없는 일회용 클래스
- 사용법 : 익명이기때문에 자신의 이름은 없고 대신해서 상속을 받는 부모나 인터페이스의 이름을 사용하여 개체를 생성하고 생성과 동시에 클래스의 내용을 채워넣는다.
public class InnerRunnableMainV2 {
public static void main(String[] args) {
log("main() start");
Runnable runnable = new Runnable() {
@Override
public void run() {
log("run() start");
}
};
Thread thread = new Thread(runnable);
thread.start();
log("main() end");
}
}
람다식과 함수형 인터페이스
- 람다식 : 함수형인터페이스(함수/메서드를 나타내는 객체)를 사용하여 익명클래스를 만들때 간단하게 표현하는 방법.
- type InterfaceName(parameter type a, b){ Overriding method statment;} 를 (a, b) -> overriding method statment로 간략화한것
- 반환타입과 이름을 지우고 매개변수 () 사이에 '->'를 입력한다. 매개변수의 type이 추론이 가능하다면 type도 제거한다. {}내 문장에 한가지일때는 {}도 생략한다.
- 함수는 클래스에 독립적이며 메서드는 클래스에 종속적이다. 자바에서는 함수(메서드)만 단독으로 존재할 수 없기때문에 람다식은 익명객체이다. 익명클래스를 생성하는 문법이 생략되어있다고 생각하면 됨. 이 객체를 담는 참조변수가 필요하고 이를 위해서 함수형 인터페이스가 도입된다.
- type InterfaceName(parameter type a, b){ Overriding method statment;} 를 (a, b) -> overriding method statment로 간략화한것
public class InnerRunnableMainV4 {
public static void main(String[] args) {
log("main() start");
Thread thread = new Thread(() -> log("run() start"));
thread.start();
log("main() end");
}
}
함수형인터페이스
- 함수형인터페이스 : 단 하나의 추상메서드만 선언된 인터페이스이며 @Fuctional Interface라는 annotaion을 사용가능하다.
- 함수형인터페이스의 역할은 람다식을 호출하기 위해서 함수형인터페이스가 method의 이름을 대신 선언해주는 것이라고 이해하면 됨
- 익명클래스를 사용한 원형 MyFunction f = new public abstract int max ( int a, int b) {return a>b ? a : b ; }
- 람다식을 사용한 축약형 MyFunction f = (a ,b) -> a>b ? a: b;
- ex : Comparator interface is a functional interface used to order the elements
- 함수형인터페이스의 역할은 람다식을 호출하기 위해서 함수형인터페이스가 method의 이름을 대신 선언해주는 것이라고 이해하면 됨
- 대표적인 함수형 인터페이스 ;
- Predicate<T> : 입력값 T를 받아 boolean을 반환하는 함수형 인터페이스.
- 주요메서드 : boolean test(T t): 이 메소드는 객체 T를 매개변수로 받아, 정의된 조건에 따라 true 또는 false를 반환함
- 부가메서드
- and(Predicate<? super T> other): 두 개의 Predicate 조건을 논리적 AND 연산으로 결합합니다.
- or(Predicate<? super T> other): 두 개의 Predicate 조건을 논리적 OR 연산으로 결합합니다.
- negate(): Predicate 조건의 논리적 부정(NOT)을 수행합니다.
- 람다식 표현 : Predicate<String> startsWithA = name -> name.startsWith("A");
- Comparable<T> : 객체가 자신의 비교 규칙을 내장하여 자연스러운 정렬 순서를 제공할 수 있게 해주는 인터페이스. .sort(object) 호출은 클래스의 compareTo 메소드를 내부적으로 사용하여 각 Person 인스턴스를 나이에 따라 정렬합니다.
- int compareTo(T o): 이 메소드는 객체 자신(this)를 매개변수로 전달된 객체 o와 비교합니다. 이 메소드의 반환 값은 다음과 같은 세 가지 경우 중 하나입니다:
- 음수 반환: 객체 자신이 매개변수 객체보다 "작다"는 것을 의미합니다.
- 0 반환: 두 객체가 같다는 것을 의미합니다.
- 양수 반환: 객체 자신이 매개변수 객체보다 "크다"는 것을 의미합니다.
- int compareTo(T o): 이 메소드는 객체 자신(this)를 매개변수로 전달된 객체 o와 비교합니다. 이 메소드의 반환 값은 다음과 같은 세 가지 경우 중 하나입니다:
- Predicate<T> : 입력값 T를 받아 boolean을 반환하는 함수형 인터페이스.
public class Person implements Comparable<Person> {
private String name;
private int age;
@Override
public int compareTo(Person other) {
// 나이를 기준으로 비교
return Integer.compare(this.age, other.age);
}
}
-
- Comparato<T> : 두 객체를 외부에서 주어진 기준으로 비교하는 데 사용됩니다. 객체의 기본 정렬 순서(Comparable 인터페이스를 통한 정렬)와 다른 방식으로 객체를 정렬하고 싶을 때 유용합니다.
- 주요메서드 : int compare(T o1, T o2): 이 메소드는 두 객체 o1과 o2를 비교하고, o1이 o2보다 작으면 음수를, 같으면 0을, 크면 양수를 반환합니다. 이 반환 값은 Collections.sort()나 Arrays.sort() 같은 정렬 메서드에서 사용되어 객체들을 정렬하는 데 활용됩니다.
- 추가메서드
- reversed(): 현재 Comparator의 반대 순서로 비교하는 새 Comparator를 반환합니다.
- thenComparing(Comparator<? super T> other): 현재 Comparator로 두 객체가 같다고 판단될 때, other Comparator를 사용하여 추가 비교를 수행합니다.
- thenComparing을 안쓰더라도 if문으로 비교결과값 ==0이면 새로운 비교로직을 적용하면 thencomparing을 쓰지않고서도 2가지이상 비교조건을 구현할 수 있음.
- static <T> Comparator<T> naturalOrder(): 객체의 자연적인 정렬 순서(Comparable을 구현한 경우)에 따라 비교하는 Comparator를 반환합니다.
- static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) 및 nullsLast(Comparator<? super T> comparator): null 값을 갖는 객체들을 각각 비교 시작이나 끝에 배치하는 Comparator를 반환합니다.
- Comparator<T> comparing( Function<? super T, ? extends U> keyExtractor ) : comparing <T>은 주로 람다 표현식이나 메소드 참조를 인자로 받습니다. 이 인자는 객체에서 특정 키를 추출하는 함수로 작동합니다. 추출된 키는 자연 순서(Comparable을 구현해야 함)에 따라 비교됩니다
- Comparato<T> : 두 객체를 외부에서 주어진 기준으로 비교하는 데 사용됩니다. 객체의 기본 정렬 순서(Comparable 인터페이스를 통한 정렬)와 다른 방식으로 객체를 정렬하고 싶을 때 유용합니다.
-
- Supplier<T> : 매개변수로 받는 값은 없고 T값을 반환함.
- Method Signature: The Supplier<T> interface has a single method, get(), which does not take any parameters and returns a value of type T:
- Supplier<LocalDate> todaySupplier = LocalDate::now;
- Supplier<T> : 매개변수로 받는 값은 없고 T값을 반환함.
-
- Consumer<T> : 매개변수로 T를 받고, 특정 행위를 수행한 후 반환값은 없음
- Consumer<String> printConsumer = System.out::println;
- Function<T R> : 일반적인 함수로 인자 T를 받고 R값을 반환함.
- Function<String, Integer> lengthFunction = String::length;
- UnaryOperator<T> : operates on a single operand and returns a result of the same type as its operand. extention of Function<T, T>.
- Consumer<T> : 매개변수로 T를 받고, 특정 행위를 수행한 후 반환값은 없음
- 메서드참조 : 하나의 메서드만을 호출하는 람다식은 메서드참조로 더 간단히 할 수 있다. 파라미터부분을 제거하고 사용되는 메서드는 문맥으로 프로그램은 파라미터에 대한 정보를 읽어들인다. 단, 아래의 불가예시와 같이 특정 인자를 사용해야되는 경우에는 람다식으로만 표현가능한 부분이 있음.
- ex 1 : (x) -> ClassName.method(x) 에서 ClassName::method로 변환
- ex 2 : (obj,x) -> obj.method(x) 에서 ClassName ::method로 변환
- 불가 : name -> name.startsWith("A") 에서 String::startsWith("A) ; 메서드참조에 매개변수부분은 넣을수 없음.
Comparator 인터페이스는 주로 다음 메소드를 정의합니다:
- int compare(T o1, T o2): 이 메소드는 두 객체 o1과 o2를 비교하고, o1이 o2보다 작으면 음수를, 같으면 0을, 크면 양수를 반환합니다. 이 반환 값은 Collections.sort()나 Arrays.sort() 같은 정렬 메서드에서 사용되어 객체들을 정렬하는 데 활용됩니다.
Comparator 인터페이스는 주로 다음 메소드를 정의합니다:
- int compare(T o1, T o2): 이 메소드는 두 객체 o1과 o2를 비교하고, o1이 o2보다 작으면 음수를, 같으면 0을, 크면 양수를 반환합니다. 이 반환 값은 Collections.sort()나 Arrays.sort() 같은 정렬 메서드에서 사용되어 객체들을 정렬하는 데 활용됩니다.
스트림
컬렉션, 배열과 같은 다양한 데이터소스를 표준화 된 방법으로 다루기 위한 객체. 배열, 컬렉션 등으로부터 데이터를 하나씩 참조하는 파이프라인. for 문의 사용을 줄여주어 간결한 코드 작성이 가능하다. 스트림은 원본으로부터 데이터를 읽기만할 뿐 원본을 바꾸지 않는다. 주로 람다식과 함께 쓰인다.
스트림은 크게 3가지로 구성됨 ; 1. Stream 생성 2. 중개 연산 3. 최종 연산 - 데이터소스객체.Stream생성().중개연산().최종연산();
1. 스트림 생성
- 컬렉션/배열에서 스트림 생성:
- 객체 배열 스트림: Stream<Object> stream = Arrays.stream(arr);
- 기본형 배열 스트림: IntStream stream = Arrays.stream(arr, fromIndex, toIndex);
- 컬렉션에서 스트림: CollectionInstance.stream()
- 스트림 빌더 사용:
- Stream<Object> stream = Stream.builder().add(element1).add(element2)...build();
- 타입을 지정한 빌더: Stream<Object> stream = Stream.<Object>builder().add(element).build();
- 무한 스트림 생성:
- Stream.generate(Supplier Interface) 메소드를 사용하여 무한 스트림(요소가 무한히 생성되는 스트림)을 만들 수 있습니다.
- 예: Stream.generate(() -> "ContentsToRepeat");
2. 중간연산
중간 연산은 스트림의 입력과 출력이 모두 스트림인 연산입니다. 즉, 중간 연산을 여러 번 반복적으로 적용할 수 있으며, 최종 연산이 수행될 때까지 실제 실행되지 않습니다.
- Filter(Predicate - 판별식) - 조건이 참인 요소들만 걸러내는 메소드입니다.
- IntStream.range(1, 10).filter(n -> n % 2 == 0); // 1부터 9까지의 짝수만 필터링
- IntStream.range (a,b) : a부터 b-1까지의 숫자 스트림을 생성, b는 포함하지않음
- IntStream.range(1, 10).filter(n -> n % 2 == 0);
- IntStream.limit(long maxSize) : 스트림의 요소를 특정개수까지만 제한하는 메소드
- IntStream.range(1, 100).limit(5); // 1부터 5까지의 스트림 생성
- sorted(): 스트림 내 요소를 정렬합니다. 기본적으로 오름차순으로 정렬됩니다.
- map (function 연산) : 스트림의 각 요소에 대해 특정 연산을 수행후 새로운 스트림 Stream<T> 을 반환하는 메소드입니다.
- Stream<T>형태로 반환하기 때문에 primitive data를 결과로 산출하는 function은 WrapperClass로 autoboxing되기때문에 mapToInt를 사용해야함.
Stream<String> strStream = Stream.of("1", "2", "3");
Stream<Integer> intStream = strStream.map(Integer::parseInt); // String → Integer
- mapToInt(Integer::parseInt) : Stream<T> 를 IntStream 으로 변환
- Stream<String> strStream = Stream.of("1", "2", "3");
- strStream.mapToInt(Integer::parseInt); // 문자열을 정수로 변환
Stream<String> strStream = Stream.of("1", "2", "3");
IntStream intStream = strStream.mapToInt(Integer::parseInt); // String → int
intStream.forEach(System.out::println);
- boxed() : 기본형(primitive) 데이터 타입을 래퍼(wrapper) 클래스로 변환합니다..
- Arrays.stream(new int[]{1, 2, 3}).boxed().collect(Collectors.toList()); // int 배열을 리스트로 변환
3. 최종연산 :
연산결과가 스트림이 아닌 연산, 스트림은 사용되면 소모되기때문에 단 한번만 사용가능
- Primitive type 생성 (Primitive type stream 전용 )
- sum() - count() - average() - min()- max()
- 객체생성
- toArray() : create an array of Object or an array of a specific type via an array constructor reference.
- ex : String[] array = stream.toArray(String[]::new);
- collect() : Collectors 클래스의 메소드를 사용하여 스트림을 collectin 객체로 변환해줌.
- ex : stream.collect(Collectors.toList()); stream.collect(Collectors.toSet());
- toArray() : create an array of Object or an array of a specific type via an array constructor reference.
- 공통
- foreach(Consumer - Class::method) : consumer functional interface를 parameter로하여 stream을 소모하여 class의 method를 실행시킴. is used for performing actions (side effects) on elements
- reduce : combine all elements of the stream into a single result. It's a model of a folding operation, where a binary operator is applied repeatedly to combine elements successively until a single value remains. first parameter is an initial value for the reduction process and as a default result if the stream is empty.
- reduce(1, (a, b) -> a * b);
- findAny(e -> e's conditional statment) : returns any element from the stream.
- 사용 : 데이터소스객체.Stream생성().중개연산().최종연산();
IntStream.range(1,N+1).filter(i->i%2==1).toArray();
'개발기술 > Java' 카테고리의 다른 글
Exception Handling & Logging (1) | 2025.03.10 |
---|---|
Java의 메모리 영역과 static의 의미 (0) | 2025.01.15 |
Java 멀티쓰레드 (0) | 2024.08.12 |
웹 스크래핑 Jsoup (0) | 2024.08.06 |
Java Dependency - Marven, Gradle, exteral libraries(Lombok etc) (0) | 2024.07.05 |