public class MyCollection<T> {
private List<T> list;
public MyCollection(List<T> list) {
this.list = list; }
// 제네릭 타입 메서드
public <U> MyCollection<U> map(Function<T, U> function) {
List<U> newList = new ArrayList<>();
foreach(d -> newList.add(function.apply(d)));
return new MyCollection<>(newList);
}
public MyCollection<T> filter(Predicate<T> predicate) {
List<T> newList = new ArrayList<>();
foreach(d -> {
if(predicate.test(d))
newList.add(d); });
return new MyCollection<>(newList);
}
public void foreach(Consumer<T> consumer) {
for (int i = 0; i < list.size(); i++) {
T data = list.get(i);
consumer.accept(list.get(i));
}
}}
public class Main {
public static void main(String[] args) {
// 메서드 체이닝 방식
// type T에 맞춰질 것이다.
new MyCollection<>(Arrays.asList(1, 2, 3, 4))
.foreach(System.out::println);
// 형태를 바꿔보기
new MyCollection<>(Arrays.asList(1, 2, 3, 4, 5))
.map(String::valueOf).foreach(System.out::println);
// 필터를 적용해보기
new MyCollection<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) .filter((i) -> i % 2 == 0).foreach(System.out::println);
// 필터를 적용해보기
int size = new MyCollection<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) .filter((i) -> i % 2 == 0).size();
System.out.println("size = " + size);
}}
Iterator
여러 데이터의 묶음을 풀어서 하나씩 처리할 수 있는 수단을 제공한다.
next()를 통해 다음 데이터를 조회할 수 있다. 역(이전데이터)으로 움직일 수는 없다.
public static void main(String[] args) {
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iter = list.iterator();
System.out.println(iter.next()); // A
System.out.println(iter.next()); // B
System.out.println(iter.next()); // C
}
Stream
JAVA8 이상에서 부터 사용 가능하다.
데이터의 연속상에서 제공되는 하나만 취급한다.
System.in / System.out 이게 모두 사실 스트림이다.
JAVA8 에서 제공되는 스트림은 input / output에 관련된 스트림과는 다르게 데이터에 관한 스트림이다.
Stream에는 map, filter, forEach 같은 고차함수(함수형 인터페이스를 사용해서 함수를 인자로 받는 함수)가 제공된다.
Stream 만들기
generator / iterator 2가지 방법이 있다.
// 스트림 만들기 1
// 스트림은 데이터의 연속이기 때문에 제너레이터를 이용하면 랜덤 값을 계속 발생시킨다.
Random r = new Random();
Stream.generate(() -> r.nextInt())
.forEach(System.out::println);
// 제한하고 싶다면?
Stream.generate(() -> r.nextInt())
.limit(10)
.forEach(System.out::println);
// 스트림 만들기 2
Stream.iterate(0, (i) -> i + 1)
.forEach(System.out::println);
스트림을 사용하면 연속된 데이터에 대해서 풍부한 고차함수들을 사용하여 강력한 기능들을 간결하게 표현할 수 있습니다.
Optional
NPE(Null Pointer Exception) - 가장 많이 발생하는 에러 중 하나이다.
자바에서는 거의 모든것이 래퍼런스이기 때문에 모든것이 null이 될 수 있다는 뜻을 가진다.
항상 null을 확인할 필요가 있다.
그래서 많이 피곤한 일들이 생겼다 이게 null이 아닌지 확인하는 작업을 해야했다.
이제부터 null 쓰지말자 ! ==> 서로 약속을 했다 : 계약을 한다 : 계약을 하고 프로그래밍을 한다.
옵셔널이 있기 전에는 EMPTY(public static final 객체)를 하나 만들어 사용했다.