자바 8에서는 람다와 메서드 참조를 제공하였고 그 결과 아래와 같이 더욱 readable 있는 코드로 리팩토링이 가능해졌습니다.
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
람다를 통해 익명클래스를 간단하게 바꾸었으며, ::isHidden 인 메서드 참조를 통해 한결 간단해진 코드가 되었습니다.
2- 코드 넘겨주기
아래는 사과 리스트에서 초록색이며, 무게가 200이 넘는 사과만 분류하는 코드입니다. - 자바 8 이전
privateenum Color {
GREEN,
RED
}
publicstaticvoidmain(String[] args){
List<Apple> appleList = Arrays.asList(new Apple(Color.RED, 200), new Apple(Color.GREEN, 30), new Apple(Color.GREEN, 300));
final List<Apple> filterdGreenAppleList = filterGreenApples(appleList);
final List<Apple> filterdGreenWithHeavyAppleList = filterHeavyApples(filterdGreenAppleList, 200);
}
@Getter@RequiredArgsConstructorprivatestaticclassApple{
privatefinal Color color;
privatefinalint weight;
}
privatestatic List<Apple> filterGreenApples(List<Apple> apples){
List<Apple> result = new ArrayList<>();
for(Apple apple: apples) {
if(Color.GREEN.equals(apple.getColor())) {
result.add(apple);
}
}
return result;
}
privatestatic List<Apple> filterHeavyApples(List<Apple> apples, int weight){
List<Apple> result = new ArrayList<>();
for(Apple apple: apples) {
if(apple.getWeight() > weight) {
result.add(apple);
}
}
return result;
}
하지만, 자바 8의 스트림 함수와 람다를 사용하면 아래와 같이 간단하게 바뀔 수 있습니다.
publicstaticvoidmain(String[] args){
List<Apple> appleList = Arrays.asList(new Apple(Color.RED, 200), new Apple(Color.GREEN, 30), new Apple(Color.GREEN, 300));
final List<Apple> filterdGreenWithHeavyAppleList = appleList
.stream()
.filter(apple -> Color.GREEN.equals(apple.getColor()))
.filter(apple -> apple.getWeight() > 200)
.collect(Collectors.toList());
}
단, filter 에 있는 조건들이 일회성이 아니라면 별도 함수로 추출해서 사용해야 합니다.
4. 스트림
이전 옛날 자바에서는 한개의 CPU만을 사용하는 단점이 있었습니다.
하지만 자바 8에서는 한개가 아닌 멀티 CPU를 점유해서 사용하도록 변경되었고 이는 성능의 극대화를 가져다 주었습니다
대표적으로 parallelStream 을 들 수 있습니다.
parallelStream은 멀티 CPU를 통해 분할로 처리할때 사용합니다.
단, Parallel Stream 작업이 독립적이면서CPU사용이 높은 작업에 사용해야합니다.
5. 디폴트 메서드와 자바 모듈
자바 8에서는 인터페이스에 디폴트 메서드를 제공합니다.
디폴트 메서드는 기존의 코드를 수정하지 않고 확장하기 위해서 만들어진 것이며,
간단하게 인터페이스에도 기본적으로 정의된 구현 메서드가 있을 수 있다고 생각하면 됩니다.
아래는 List의 default sort 함수입니다.
defaultvoidsort(Comparator<? super E> c){
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
6. 함수형 프로그래밍에서 가져온 다른 유용한 아이디어
자바 8에서 제공되는 기능들은 대체로 함수형 프로그래밍 특성을 가져다 주는 것입니다.
이런 함수형 프로그래밍의 패러다임을 가져오면서 많은 프로그램에 도움이 되는 아이디어가 나왔습니다.
한가지 예로, null을 회피하는 방법이며 자바에서는 Optional<T> 라는 컨테이너 클래스를 통해 제공하고 있습니다.
대게, 스트리밍이라하면 실시간 처리로 알고 있습니다. 스파크는 마이크로 배치로 짧게 여러번 수행하여 스트리밍 처리를 제공합니다.
2. 주요 용어
1) 스트리밍 컨텍스트
스파크 스트리밍을 수행하기 위해서는 스트리밍 모듈에서 제공하는 스트리밍 컨텍스트를 사용해야 합니다.
아래는 스트리밍 컨텍스트를 생성하고 사용하는 예제입니다. - (스칼라)
val conf = new SparkConf()
conf.setMaster("local[*]")
conf.setAppName("StreamingSample")
conf.set("spark.driver.host", "127.0.0.1")
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc, Seconds(3))
val rdd1 = sc.parallelize(List("Spark Streaming Sample ssc"))
val rdd2 = sc.parallelize(List("Spark Queue Spark API"))
val inputQueue = Queue(rdd1, rdd2)
val lines = ssc.queueStream(inputQueue, true)
val words = lines.flatMap(_.split(" "))
words.countByValue().print()
ssc.start()
ssc.awaitTermination()
예제에서 볼 수 있듯이 StreamingContext는 SparkContext에서 생성 할 수 있습니다.
추가로, 어느 주기로 수행할 지의 정보도 같이 넘겨야 합니다.
예제에서는 Seconds(3)을 통해 3초에 한번씩 수행되도록 하였습니다.
그리고, 마지막에 있는 start 메소드를 실행해야만 스파크 스트리밍은 수행됩니다.
또한, awaitTermination 를 통해 임의로 애플리케이션이 종료되지 않도록 합니다.
종료는 개발자가 직접 어떤 시점 혹은 상황에 하도록 추가하여야 합니다.
2) DStream (Discretized Streams)
DStream은 RDD 와 같이 스파크에서 스트리밍을 위해 제공하는 데이터 모델입니다.
단순하게 RDD의 시퀀스로 이해하시면 되며, 지정한 배치 간격마다 input 에서 데이터를 가져와 DStream으로 변경하면서 처리하게 됩니다.
인자로 받은 문자열 중 나란히 있는 중복문자를 반복적으로 제거하고, 남은 문자열을 반환하는 문제입니다.
위 예제를 보면 아래와 같이 처리가 흐르게 됩니다.
1. abbaca -> bb 제거
2. aaca -> aa 제거
3. ca 반환
저는 아래와 같이 풀이하였습니다.
classSolution:defremoveDuplicates(self, S: str) -> str:
stack = []
stack.append(S[0])
for i in S[1:]:
if stack and stack[-1] == i:
stack.pop()
else:
stack.append(i)
return''.join(stack)
stack으로 이용할 list를 하나 만들었습니다.
그 후, 문자열을 iterate하며 stack에서 peek한 결과와 동일하면 pop 아니면 append 하였습니다.