[내배캠]자바 문법 뽀개기-Generics, Lambda, Stream

손홍서·2022년 5월 17일
0

Java

목록 보기
5/11
post-thumbnail

Generics

다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능을 의미
객체 타입을 컴파일 시에 체크하여 안정성이 높아진다. -> 의도하지 않은 타입의 객체가 저장되는 것을 막고 잘못된 형변환을 막는다.

  • 제네릭스의 형식
public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}
  • 자주 사용되는 타입인자 약어
- <T> == Type
- <E> == Element
- <K> == Key
- <V> == Value
- <N> == Number
- <R> == Result

Lambda

람다식은 식별자 없이 실행 가능한 함수
함수의 이름을 따로 정의하지 않아도 곧바로 함수처럼 사용 가능하다.(익명함수라고도 부른다)
문법이 간결해 편리하다.
하지만 재사용이 불가능하고, 코드가 지저분해 질 수 있다.

  • 람다식의 형식
    • '→'의 의미는 매개변수를 활용하여 {}안에 있는 코드를 실행한다는 것입니다.
  [기존의 메소드 형식]
  반환타입 메소드이름(매개변수 선언) {
      수행 코드 블록
  }

  [람다식의 형식]
  반환타입 메소드이름(매개변수 선언) -> {
      수행 코드 블록
  }
public class LambdaPrac {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("korea");
        list.add("japan");
        list.add("france");
        
        Stream<String> stream = list.stream();
        //여기서 lamda식은 list에서 하나씩 꺼내서 str변수에 저장해줘 -> 이걸 대문자로 바꿔줘
        stream.map(str -> str.toUpperCase()).forEach(it -> System.out.println(it));

        Stream<String> stream2 = list.stream(); //stream 한 번 사용하면 끝 다시 만들어줘야된다.
        //길면 {}를 사용 대신 return 해줘야됨
        stream2.map(str -> {
            System.out.println(str);
            return str.toUpperCase();
        }).forEach(System.out::println);

        System.out.println(list);
    }
}

Stream

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

  • 스트림의 특징
    • 스트림은 데이터 소스를 변경xxx
    • 스트림은 작업을 내부적으로 반복 처리
    • 스트림은 컬렉션의 요소를 모두 읽고 나면 닫혀서 재사용이 불가능 -> 필요할 경우 재생성
class Sale {
    String fruitName;
    int price;
    float discount;

    public Sale(String fruitName, int price, float discount) {
        this.fruitName = fruitName;
        this.price = price;
        this.discount = discount;
    }
}

public class StreamPrac {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("서울");
        list.add("부산");
        list.add("대구");
        list.add("서울");

        System.out.println(list);

        System.out.println("\nlist에서 2개만 꺼내기");
        List<String> result = list.stream() //list를 stream으로 바꾸고
                .limit(2) //나는 2개만 꺼낼거야
                .collect(Collectors.toList()); //이렇게 stream 처리된 애들을 하나로 모을건데 또 다른 리스트로 만들거야
        System.out.println(result);

        System.out.println("\nlist -> transformation -> set");
        Set<String> set = list.stream()
                .filter("서울"::equals)
                .collect(Collectors.toSet());
        System.out.println(set);

        System.out.println("\narray -> transformation -> set");
        String[] arr = {"SQL", "Java", "Python"};
        Stream<String> stringStream = Arrays.stream(arr);
        stringStream.forEach(System.out::println);


        System.out.println("\nstream 활용");
        List<Sale> sales = Arrays.asList(
                new Sale("Apple", 5000, 0.05f),
                new Sale("Orange", 4000, 0.2f),
                new Sale("Grape", 2000, 0)
        );
        sales.stream().map(sale -> Pair.of(sale.fruitName, sale.price * (1 - sale.discount)))
                .forEach(pair -> System.out.println(pair.getLeft() + " 실구매가 " + pair.getRight() + "원 입니다."));

        List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //첫번째 요소와 수행할 함수를 적으면 reduce 연산
        System.out.println(intList.stream().reduce(0, Integer::sum)); //0+1 = 1 -> 1+2 = 3 -> 3+3 =6 ... => 55

        List<String> names = Arrays.asList("김정우", "김호정", "이하늘", "이정희", "박정우", "박지현", "정우석", "이지수");
        long count = names.stream()
                .filter(name -> name.startsWith("이"))
                .count();
        System.out.println("\ncount = " + count);

    }
}

profile
Hello World!!

0개의 댓글