JAVA, Stream, Lambda

Stream (java.util)

  • Collection의 요소를 하나씩 참조하여 Lambda식으로 처리할 수 있게 해주는 일종의 반복자

Input/Output Stream (java.io)

- 스트림
: 프로그램(파일, n/w 등)과 I/O객체를 연결하여 데이터를 송수신 하는 길
: InputStream : data를 읽어 들이는 객체, OutputStream : data를 써서 보내는 객체

바이트 스트림 : binary data 입출력 , 이미지 동영상 송수신에 사용
문자스트림 : text data 입출력하는 스트림 , html text파일 송수신 사용

직렬화/역직렬화 : 객체 <-> 데이터 스트림

예제

List<String> names = Arrays.asList("hyemi", "haen", "minjun");

// 일반 방식
int count = 0;
for (String name : names) {
  if (name.contains("h"))
    count++;
}
System.out.println("count : " + count);

// 스트림 이용
count = 0;
count = (int) names.stream().filter(x -> x.contains("h")).count();
System.out.println("count (stream) : " + count);

// 차례로 실행된다
System.out.println(names.stream().filter(el -> {
		System.out.println("call filter...");
		return el.contains("h");
}).map(el -> {
	  System.out.println("call map...");
	  return el.toUpperCase();
}).findFirst());
// 결과 : Optional[HYEMI]

Stream 사용법

  • Collections같은 객체 집합.스트림생성().중개연산().최종연산();
  • names.stream().filter(x -> x.contains(“h”)).count();
  • ”.”으로 연계할 수 있게 하는 방법 : 파이프라인

중개연산

  • Filter, Peek, Sorted, Limit, Distinct, Skip, map, mapToint, mapToLong, mapToDouble

Filter

  • 조건으로 거른다.
  • names.stream().filter(x -> x.contains(“h”)).count();

limit

  • ages.stream().filter(x -> x > 3).limit(4).forEach(x -> System.out.println(x));

map

  • 특정 조건을 적용해서 변환
	names.stream().map(n -> n.toUpperCase())
					  .forEach(n-> System.out.println(n));

최종연산

  • count(), min(), max(). sum(), average(), forEach, iterator…
  • reduce()

    List<Integer> ages = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    System.out.println(ages.stream().reduce((b, c) -> b + c).get());  // 55
    

Lambda

  • 메소드를 하나의 식으로 표현한것
  • 익명메소드 생성 문법(이름과 반환값이 없어지기 때문)
  • 메소드를 지칭하는 명칭없이 구현부만 선언

Lambda 사용이유

  • interface가 가지고 있는 method를 간편,즉흥적으로 구현해서 사용하는 것이 목적

람다의 기본식

람다의 기본식 : (매개변수) -> {실행문}
  • 람다식을 사용하기 위해서는 구현할 인터페이스가 필요하다. (함수형 인터페이스)
  • 람다식으로 구현하기 위한 인터페이스에는 한개의 추상메소드만 가지고 있어야 한다
  • 이런 인터페이스를 미리 함수적 인터페이스 라고 부른다.

예시

interface Calculator {
	int plusOne(int n);
}

public static void main(String[] args) {

	// 익명클래스
	Calculator calc = new Calculator() {

		@Override
		public int plusOne(int n) {
			return n + 1;
		}
	};

	System.out.println(calc.plusOne(3));

	// 람다식
	Calculator calc2 = (num1) -> {
		return num1 + 1;
	};
	System.out.println(calc2.plusOne(4));
}

예시2

@FuntionalInterface
interface Calculator {
  int calc(int n);
}

class Driver {
  public static void main(String[] args) {
    int n = 2;

    // int n과 구별하기 위해 람다식에는 v라는 변수명을 사용.
    printCalc(n, v -> v + 1); // n + 1, 출력값 3
    printCalc(n, v -> v - 1); // n - 1, 출력값 1
    printCalc(n, v -> v * 2); // n * 2, 출력값 4
  }

  public static void printCalc(int n, Calculator cal) {
    System.out.println(cal.calc(n));
  }
}

참고