스트림의 중간연산

sion Jeong·2024년 7월 15일
0

1. 스트림 자르기: skip(), limit()

💡 실습

  • rangeClosed(1, 10) 1~10까지(마지막 포함)
  • skip(3) 으로 3개 건너뛰고 limit(5) 로 5개만 담긴 스트림을 반환함

2. 스트림 요소 걸러내기: filter(조건식), distinct()

  • filter(조건식) → 조건에 맞지 않는 요소를 제거
  • distinct() → 중복제거

💡 실습

  • distinct() 메서드로 → 중복을 걸러냄

  • filter(2의 배수) ⇒ 2의 배수가 아닌 것들은 다 걸러냄

  • filter() 메서드는 → 중간연산이기 때문에 → 여러번 쓸 수 있다.
  • 2의 배수이면서 3의 배수인 것만 추출한다. (6)

3. 스트림 정렬하기: sorted()

  • sorted() → 스트림을 기본정렬함
  • sorted(정렬기준) → 정렬 기준으로 스트림을 정렬

💡 스트림을 정렬할때 사용하는 Comparator인터페이스의 comparing()메서드 사용

  • comparing()으로 → 정렬 기준을 제공합니다.
  • 추가 정렬 기준이 필요할때는 thenComparing()을 이용합니다.(정렬기준 여러개)
  • 예시에선 정렬기준이 3개가 된다.

실습

    public static void main(String[] args) {

        Stream<Student> studentStream = Stream.of(
                new Student("이자바", 3, 300),
                new Student("김자바", 3, 300),
                new Student("인자바", 3, 300),
                new Student("박자바", 3, 300),
                new Student("소자바", 3, 300),
                new Student("나자바", 3, 300),
                new Student("감자바", 3, 300)
        );

        studentStream.sorted(Comparator.comparing(Student::getBan).reversed() //1. 반별 정렬 + 역순정렬
                .thenComParing(Comparator.naturalOrder())) //2. 기본정렬
        .forEach(System.out::print);

    }

4. 스트림 요소 변환하기: map()

  • T타입의 스트림이 → R타입의 스트림으로 바뀌는것

  • File타입의 스트림을 → String 타입으로 변환을 했다
  • map() 메서드를 사용해서
    • File 객체에 → getName 메서드를 사용해 → 파일 이름을 추출해 String 으로 반환한다.
  • 이렇게 스트림의 요소가 map() 메서드를 통해 fileString 로 변환되는것이다.
 public static void main(String[] args) {

        File[] fileArr = { //파일 배열 생성
                new File("Ex1.java"),
                new File("Ex1.bak"),
                new File("Ex2.java"),
                new File("Ex1"),
                new File("Ex1.txt")
        };

        Stream<File> fileStream = Stream.of(fileArr); //배열을 -> 스트림으로 생성

        //map() 으로 Stream<File>을 -> Stream<String)으로 변환
        Stream<String> fileNameStream = fileStream.map(File::getName);//(getName메서드 반환타입이 String)
        fileNameStream.forEach(System.out::println); //모든 파일의 이름을 출력 (최종연산)

        fileStream = Stream.of(fileArr);//배열을 -> 스트림으로 생성 (스트림 다시 생성)

        fileStream.map(File::getName) //map() 으로 Stream<File>을 -> Stream<String)으로 변환 (getName메서드 반환타입이 String)
                .filter(s -> s.indexOf('.') != -1) //확장자가 없는것 거르기 제외
                .map(s -> s.substring(s.lastIndexOf('.') + 1)) //확장자만 추출
                .map(String::toUpperCase) //모두 대문자로 변환
                .distinct() //중복 제거
                .forEach(System.out::println); //JAVA BAK TXT

    }

  • File :: getName 파일의 이름을 뽑이내고 map() 메서드 사용해→ 타입을 변환한다,
  • filter(조건식)을 통해 .이 없는파일이름 다 제거
  • substring으로 확장자 뽑음
  • map()메서드로 String 을 → 대문자로 변환

💡 실습

   String[] strArr = { //문자열 배열
                "Inheritance", "Java", "Lambda", "stream", "OptionalDouble", "intStream", "count", "sum"
        };

//Stream<String>을 -> Stream<Integer>으로 변환
Stream<Integer> intStream1 = Stream.of(strArr).map(String::length); //중간연산 map, 각각 배열의 길이요소를 -> Integer타입으로 변환
		intStream1.forEach(System.out::println);
		
		
//Stream<String>을 -> IntStream으로 변환 (IntStream)은 기본형 스트림
IntStream intStream1 = Stream.of(strArr).mapToInt(String::length);
IntStream intStream2 = Stream.of(strArr).mapToInt(String::length);
IntStream intStream3 = Stream.of(strArr).mapToInt(String::length);
IntStream intStream4 = Stream.of(strArr).mapToInt(String::length);

5. 스트림의 요소를 소비하지 않고 엿보기 : peek()

  • .forEach와 같다. (최종연산) (반환타입 void, 스트림 아니다)
  • 차이점은 peek() 는 중간연산이라(반환타입 Stream) → 스트림을 소비하지 않는다 (무한 확인 가능)

💡 실습

  • 중간중간 잘 되고있는지 확인하는 용도로 쓴다

  • 중간 작업결과 확인용도로 사용 (디버깅 용도)

  • 피크를 중간중간 넣어서 잘 진행되고 있는지 디버깅 용도로도 사용이 가능하다


6. 스트림의 스트림을 → 스트림으로 변환 : flatMap()

  • 여러개의 스트림 배열을 → 하나의 스트림 배열로 합치고 싶을때 사용한다.
  • 혹은 하나의 배열을 → 여러개로 나누고 싶을때

요구사항

  • 여러개의 문자열 배열을 → 아래처럼 문자열 배열 하나로 합치고 싶다
  • flatMap() 메서드를 사용하면됨
    Stream<String[]> strArrStrm = Stream.of(new String[]{"abc", "def", "ghi"},
                                           new String[]{"ABC", "GHI", "pqr", "JKLMN"});


💡 map() 메서드와 flatMap() 메서드의 차이

  • map()을 사용하면 아래의 결과가 나옴
    • 여러 배열이 하나로 합쳐지는게 아닌 → 스트림 안에 스트림 안의 배열로 생김
    Stream<String[]> strArrStrm = Stream.of(new String[]{"abc", "def", "ghi"},
                                           new String[]{"ABC", "GHI", "pqr", "JKLMN"});

  • 하지만 flatMap() 을 사용하면
    • 여러 배열이 → 하나의 배열로 합쳐질 수 있다.
    Stream<String[]> strArrStrm = Stream.of(new String[]{"abc", "def", "ghi"},
                                           new String[]{"ABC", "GHI", "pqr", "JKLMN"});


💡 실습

    public static void main(String[] args) {

        Stream<String[]> strArrStrm = Stream.of(
                new String[]{"abc", "def", "jkl"},
                new String[]{"ABC", "GHI", "JKL"}
        );

        Stream<String> strStrm = strArrStrm.flatMap(Arrays::stream);

        strStrm.map(String::toLowerCase) //스트림의 요소를 -> 모두 소문자로 변경
                .distinct() //중복제거
                .sorted() //정렬
                .forEach(System.out::println);
    }
 
//출력
abc
def
ghi
jkl
public static void main(String[] args) {

        String[] lineArr = {"Believe or not It is true", "Do or do not There is no try"};

        Stream<String> lineStream = Arrays.stream(lineArr);
        lineStream.flatMap(line -> Stream.of(line.split(" +"))) //스페이스 바로 나누기
                .map(String::toLowerCase) 
                .distinct()
                .sorted()
                .forEach(System.out::println);

    }
 

//출력
believe
do
is
it
no
not
or
there
true
try
profile
개발응애입니다.

0개의 댓글