동석쿠
프로그래밍 공부
동석쿠
전체 방문자
오늘
어제
  • 공부 (80)
    • 공부기록 (64)
      • 웹개발 (6)
      • Java (7)
      • cs 공부 (3)
      • http 웹 기본 지식 (8)
      • 자바 스프링 (20)
      • 개인 미니프로젝트 (3)
      • 알고리즘 공부 (6)
      • 면접준비 (2)
      • 프론트공부 (8)
      • 파이썬 플라스크 (1)
    • 항해99 기록 (14)
      • 회고록 (10)
      • 팀프로젝트 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자바
  • API
  • 프로그래머스
  • 스프링
  • 자바스크립트
  • 항해99
  • 알고리즘
  • 문법
  • 리프레시토큰
  • Get
  • 리프레쉬토큰
  • 리액트
  • JPA
  • 파이썬
  • 상속
  • 스프링부트
  • Post
  • lombok
  • 리스트
  • Java

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
동석쿠

프로그래밍 공부

Java (제네릭스)(람다)(스트림)
공부기록/Java

Java (제네릭스)(람다)(스트림)

2022. 1. 9. 10:59

제네릭스(Generics)란?

다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능을 의미한다.

 

제네릭스를 왜 사용해야할까? :

→ 객체의 타입을 컴파일 시에 체크하기 때문에 안정성이 높아진다.

(의도하지 않은 타입의 객체가 저장되는 것을 막고 잘못된 형변환을 막을 수 있기 때문)

 

제네릭스의 형식

public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}

자주 사용되는 타입인자 약어

  • <T> == Type
  • <E> == Element
  • <K> == Key
  • <V> == Value
  • <N> == Number
  • <R> == Result

우리는 이미 제네릭스를 사용하고 있었는데, 제네릭스를 가장 잘 사용한 예제는 바로 Collection이다.

Collection 클래스를 살펴보면서 제네릭스가 어떻게 사용되었는지 확인해보자

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Main {
    public static void main(String[] args) {

        List<String> list = new ArrayList();
        Collection<String> collection = list;
    }
}

<>안에 String이 들어있는데 <>안에 어떠한 타입을 선언해주어 해당 List, Collection등이 사용할 객체의 타입을 지정해준다는 뜻이다. 이렇게 되면 List와 Collection은 String타입만 다루게 된다. 이는 다룰 객체의 타입을 미리 명시하여 객체의 형변환을 사용할 필요없게 하며, 내가 사용하고 싶은 타입만 사용할 수 있게 해주는 효과가 있다.

 

이렇게 제네릭스를 사용하면 크게 2가지의 장점이 있는데

 

1.타입의 안전성 : 의도하지 않은 타입의 객체가 저장되는 것을 막고, 다른 타입의 객체로 인한 타입 형태가 맞지 않아

                       발생하는 문제를 없애준다.

2.불필요한 형변환을 줄여 코드를 간결하게함 : 타입을 미리 명시함으로써 다른 타입의 객체가 저장되지 않아 객체를

                                                            꺼내 사용할 시 형변환을 통한 타입을 맞출 필요가 없어 코드를

                                                            간결하게 줄일 수 있다.

 

람다식(Lambda expression)이란

→"식별자 없이 실행 가능한 함수"라고 말할 수 있다. 즉, 함수의 이름을 따로 정의하지 않아도 곧바로

함수처럼 사용할 수 있는 것. 문법이 간결하여 보다 편리한 방식이다. (익명함수라고도 한다)

→람다식이 코드를 보다 간결하게 만들어주는 역할을 하지만 그렇다고 무조건 좋다고만 이야기 할 순 없다.

 

왜그럴까?

→람다를 사용하여서 만든 익명 함수는 재사용이 불가능하다.

→람다만을 사용할 경우 비슷한 메소드를 중복되게 생성할 가능성이 있으므로 지저분해질 수 있다.

 

람다식의 형식

'→'의 의미는 매개변수를 활용하여 {}안에 있는 코드를 실행한다는 뜻

[기존의 메소드 형식]
반환타입 메소드이름(매개변수 선언) {
    수행 코드 블록
}

[람다식의 형식]
반환타입 메소드이름(매개변수 선언) -> {
    수행 코드 블록
}

어떠한 형식인지 알게 됬으니 아래 예제를 확인해보자.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        ArrayList<String> strList = new ArrayList<>(Arrays.asList("korea", "japan", "china", "france", "england"));
        Stream<String> stream = strList.stream();
        stream.map(str -> str.toUpperCase()).forEach(System.out::println);
    }
}

따로 메소드이름을 적지 않아도 메소드가 정상 작동하는 것을 확인할 수 있다.

 

위의 예제에서 :: 가 사용되었는데. 이는 자주 사용되는 람다 표현식으로 ::(이중 콜론 연산자) 라고 한다.

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> cities = Arrays.asList("서울", "부산", "속초", "수원", "대구");
        cities.forEach(System.out::println);
    }
}

이중 콜론 연산자는 매개변수를 중복해서 사용하고 싶지 않을 때 사용한다. 출력결과를 보면 cities의 요소들이 하나씩 출력된다. 즉 cities.forEach(x -> System.out.println(x));와 똑같은 의미다.

 

스트림(stream)이란

  • 스트림은 곧 '데이터의 흐름'.
  • 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 반복자.
  • 스트림을 활용해서 필터링,데이터 변경, 다른 타입이나 자료구조로 변환 등을 할 수 있다.

스트림의 특징

  • 스트림은 데이터 소스를 변경하지 않는다.
  • 스트림은 작업을 내부적으로 반복 처리한다.
  • 스트림은 컬렉션의 요소를 모두 읽고 나면 닫혀서 재사용이 불가능하다. 그러므로 필요할 경우 재생성을 해야한다.

스트림의 구조

1. 스트림 생성

- 스트림을 이용하기 위해 먼저 스트림을 생성해야한다.

- Stream<T> Collection.stream() 을 이용하여 해당하는 컬렉션을 기반으로하는 스트림을 생성할 수있다.

 

2. 중간 연산

- 중간 단계로써 데이터의 형변환 혹은 필터링, 정렬 등 스트림에 대한 가공을 해준다.

- map(변환) / sorted(정렬) / skip(스트림 자르기) / limit(스트림 자르기) 등이 있다.

 

3. 최종 연산

- 스트림의 요소를 소모해서 결과를 반환하는 단계. 최종 연산 이후에는 스트림이 닫히게 되고 더 이상 사용할 수 없다.

- 최종 연산의 결과값은 단일 값일 수도 있으며 배열 혹은 컬렉션일 수도 있다.

- collect()를 이용해서 다른 콜렉션으로 바꾸는 것, reduce를 이용해서 incremental calculation하는 것도 가장 많이 쓰이는 패턴이다.

 

스트림 예제 : Array를 Stream으로 변환

import java.util.Arrays;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        String[] arr = {"엑셀보다 쉬운 SQL", "웹개발 종합반",
                "알고보면 알기쉬운 알고리즘", "웹개발의 봄,Spring"};
        Stream<String> stringStream = Arrays.stream(arr);
        ((Stream<?>) stringStream).forEach(className -> System.out.println("수업명 : " + className));
        System.out.println();
    }
}

스트림 예제 : reduce를 이용한 계산

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> numArr = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer result = numArr.stream().reduce(0, Integer::sum);
        //reduce와 sum을 활용하여 1부터 10까지 더하게 됩니다.
        System.out.println(result);
    }
}

 

 

'공부기록 > Java' 카테고리의 다른 글

Java 해쉬함수  (0) 2022.01.15
Java (네트워킹)  (0) 2022.01.10
Java (예외,에러처리)(날짜와 시간 다루기)(컬렉션)  (0) 2022.01.08
Java 객체지향언어 (클래스,인스턴스,메소드,생성자,상속,접근제어자,추상클래스,인터페이스)  (0) 2022.01.06
Java문법 (변수와 상수)(자료형)(연산자)(조건문과반복문)  (0) 2022.01.05
    '공부기록/Java' 카테고리의 다른 글
    • Java 해쉬함수
    • Java (네트워킹)
    • Java (예외,에러처리)(날짜와 시간 다루기)(컬렉션)
    • Java 객체지향언어 (클래스,인스턴스,메소드,생성자,상속,접근제어자,추상클래스,인터페이스)
    동석쿠
    동석쿠

    티스토리툴바