-
자바 / 스트림 Stream프로그래밍/JAVA 자바 2021. 9. 12.반응형
package streamEx; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; public class Ex001 { public static void main(String[] args) { List<String> list = Arrays.asList("A","B","C","D","E"); // 컬렉션 사용 예 Iterator<String> it = list.iterator(); while(it.hasNext()) { String s = it.next(); System.out.print(s+" "); } System.out.println(); for(String s : list) { System.out.println(s); } System.out.println(); // 스트림 사용 예 Stream<String> stream = list.stream(); // 스트림은 일회성임 데이터를 전송을 하지만 가지고 있지 않음 // 그래서 다시 또 출력을 하려면 다시 스트림 만들어서 데이터 다시 전송해야함 // stream.forEach(s -> System.out.println(s)); // 람다식 stream.forEach(System.out::println); // 메소드 참조 System.out.println(); } }
- 스트림은 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해줌
- Iterator랑 역할은 똑같은데 람다식으로 처리가 가능함, 곧 코드가 더 간결해짐
- 대신 스트림은 일회용임 = 재사용 불가
- list에 담긴 값들을 출력하기 위해서는 Iterator객체 만들어서 hasNext로 반복문을 돌려줘야 했었음
- 스트림을 사용하면 한줄로 표현 가능
String 형태 Stream 만들고 리스트를 스트림으로 담는다.
그리고 출력 해주면 된다.
- 출력 할 때는 람다식을 이용해서 출력도 가능하고
- 람다식이 가능하면 메소드 참조도 가능하다
package streamEx; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class Ex002 { public static void main(String[] args) { List<String> list = Arrays.asList("X","A","B","F","A","C","B","S"); // 최종 연산이 수행되기 전 중간 연산은 수행되지 않는다.( 지연 연산 ) Stream<String> stream = list.stream(); stream.distinct() // 중간 연산 (중복제거) .limit(5) // 중간 연산(주어진 숫자만큼 스트림) / 처음 부터 5개 가져옴 .sorted() // 중간 연산(정렬) .forEach(System.out::println); // 최종 연산 // 최종 연산은 스트림의 요소를 소모한다 / 즉 한번만 연산 가능 하다. //stream.forEach(System.out::println); // 에러임 이미 최종연산이 끝났기 때문에 } }
- 스트림에는 중간 연산 과 최종 연산이 있음
- 스트림은 최종 연산이 끝나면 더이상 사용 불가능 함
- 중간 연산에서 중복제거(distinct), 몇개만 가져올 건지(limit), 정렬 여부(sorted) 를 사용 할 수 있음
- 최종연산 = 즉 출력은 forEach로 함.
package streamEx; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.stream.IntStream; import java.util.stream.Stream; public class Ex003 { public static void main(String[] args) { // 스트림 생성 방법 // 컬렉션에서 생성하기 List<String> list = Arrays.asList("A","B","C"); Stream<String> s1 = list.stream(); s1.forEach(System.out::println); System.out.println(); // 배열에서 생성하기 String [] ss = new String[] {"A","B","C"}; Stream<String> s2 = Stream.of(ss); s2.forEach(System.out::println); System.out.println(); // 배열에서 생성하기 2 Stream<String> s3 = Arrays.stream(new String [] {"A","B","C"} ); s3.forEach(System.out::println); System.out.println(); // 특정 범위의 수에서 생성 IntStream s4 = IntStream.range(1, 5); // end는 미포함 s4.forEach(System.out::println); System.out.println(); IntStream s5 = IntStream.rangeClosed(1, 5); // end 포함 s5.forEach(System.out::println); System.out.println(); // 임의의 수에서 생성 IntStream s6 = new Random().ints(); // 무한 스트림 s6.limit(5).forEach(System.out::println); System.out.println(); IntStream s7 = new Random().ints(5); // 난수 5개 s7.forEach(System.out::println); System.out.println(); // 두 스트림 결합 Stream<String> s11 = Stream.of(new String[] {"A","B","C}"} ); Stream<String> s12 = Stream.of(new String[] {"X","Y","Z"} ); Stream<String> s13 = Stream.concat(s11, s12); s13.forEach(System.out::print); System.out.println(); } }
- 컬렉션에서 생성하는 방법은 list를 사용하고 Arrays.aslist를 사용함
- 배열에서 사용 하는 방법은 평범하게 배열을 만들고 그냥 forEach로 출력
(배열 생성 2번째 방법은 그냥 문장 2개를 합쳐논 거)
- 특정 범위까지 수 뽑아 내는 건 IntStream을 사용함
(range(1,5)는 1~4까지만 나오고 rangeClose(1,5)는 1~5까지 나온다.)
- IntStream 만들때 new Random().ints()를 하게 되면 무한 스트림이 된다.
package streamEx; import java.util.Comparator; import java.util.stream.IntStream; import java.util.stream.Stream; public class Ex004 { public static void main(String[] args) { // 중간 연산 IntStream s1 = IntStream.range(0, 10); // 0~9 IntStream s2 = IntStream.range(0, 10); IntStream s3 = IntStream.range(0, 10); // skip(n) : 처음부터 n개 만큼 제외 s1.skip(4).forEach(System.out::print); System.out.println(); // limit(n) : 처음부터 n개로 이루어진 스트림 s2.limit(5).forEach(n -> System.out.print(n+" ")); System.out.println(); // 3개 건너뛰고 5개 출력 s3.skip(3).limit(5).forEach(n -> System.out.print(n + " ")); System.out.println(); IntStream s4 = IntStream.of(7,5,5,2,1,2,3,5,4,6); IntStream s5 = IntStream.of(7,5,5,2,1,2,3,5,4,6); // 중복 제거하기 s4.distinct().forEach(n -> System.out.print(n + " ")); System.out.println(); // 홀수만 출력 s5.filter(n -> n%2 != 0).forEach(n -> System.out.print(n + " ")); System.out.println(); Stream<String> s6 = Stream.of("html","css","java","javascript"); Stream<Integer> s7 = Stream.of(7,5,2,1,3,4,6); // 정렬 s6.sorted().forEach(n -> System.out.print(n+" ")); System.out.println(); // 정렬 : 역순 s7.sorted(Comparator.reverseOrder()).forEach(n -> System.out.print(n + " "));; System.out.println(); // 스트림 변환 Stream<String> s8 = Stream.of("html","css","java","javascript"); // map(Function<? super T, ? extends R> m) : 입력 T 타입의 요소를 R 타입의 요소로 변환한 새로운 스트림 반환 s8.map(s -> s.length()).forEach(n -> System.out.print(n + " ")); System.out.println(); // 글자수를 나타냄 } }
- 스트림의 여러지 사용 형태의 예시 -
- 정렬하기 => s6.sorted().forEach 오름차순
- 내림차순 정렬 => s6.sorted(Comparator.reverseOrder()).forEach 사용
- 전부 스트림의 중간 연산임
package streamEx; import java.util.stream.IntStream; import java.util.stream.Stream; public class Ex005 { public static void main(String[] args) { // 스트림 최종 연산 IntStream s1 = IntStream.of(30,100,70,80); IntStream s2 = IntStream.of(30,100,70,80); // count(), max(), min() long n = s1.count(); System.out.println(n); int a = s2.max().getAsInt(); System.out.println(a); IntStream s3 = IntStream.of(30,100,70,80); IntStream s4 = IntStream.of(30,100,70,80); // sum(), average() System.out.println(s3.sum()); System.out.println(s4.average().getAsDouble()); IntStream s5 = IntStream.of(30,100,70,80); IntStream s6 = IntStream.of(30,100,70,80); System.out.println(s5.anyMatch(x -> x > 80)); // 하나라도 조건에 만족하면 true System.out.println(s6.allMatch(x -> x > 80)); // 모두 조건에 만족해야 true // 문자열을 : 으로 결합 // reduce()는 첫번째와 두번째 요소를 연산 후 그 결과와 세번째 요소와 연산 Stream<String> s7 = Stream.of("A","B","C","D"); String str = s7.reduce("시작", (x1,x2) -> x1+":"+x2); System.out.println(str); } }
- 스트림의 최종 연산
- count(), max(), min(), sum(), average() 등 이 가능하다.
- 복잡한 조건문 없이도 null 값으로 인해 발생하는 예외를 처리 할 수 있음.
package streamEx; import java.util.Optional; public class Ex006 { public static void main(String[] args) { // TODO Auto-generated method stub Optional<String> opt1 = Optional.empty(); // 빈 Optional 객체 System.out.println(opt1.orElse("빈객체")); // orElse(other) = 객체가 null이 아니면 그 값을 반환하고 null이면 other 반환 String s = null; s = "123"; Optional<String> opt2 = Optional.of(s); // of(value) = value 값이 null 아닌 경우 사용 int n = opt2.filter(x -> x.length() > 0).map(Integer::parseInt).get(); // get() : Optional에 저장된 값 System.out.println(n); s = null; Optional<String> opt3 = Optional.ofNullable(s); // ofNullable() : 객체가 null인지 아닌지 모를 경우에 사용 System.out.println(opt3.orElse("빈 객체")); // ifPresent() = 객체가 null이면 false s = "abc"; Optional<String> opt4 = Optional.ofNullable(s); opt4.ifPresent(t -> System.out.println(t.charAt(0))); // a s = "null"; Optional<String> opt5 = Optional.ofNullable(s); opt5.ifPresent(t -> System.out.println(t.charAt(0))); // 출력 안됨 } }
- Optional에서는 null을 가지고 할 수 있는게 있다.
- orElse = 객체가 null이 아니면 그 값을 반환하고, null이면 other를 반환함
- ifPresent() 를 통해서 null이면 false를 반환하는 점을 이용해서 null 여부를 알 수 있음. (get을 통해 접근)
반응형'프로그래밍 > JAVA 자바' 카테고리의 다른 글
자바 - 특수 문자 출력 하는 2가지 방법 (0) 2024.04.28 람다식(2) / 메소드 참조 (0) 2021.09.10 자바 람다식(1) 개념 (0) 2021.09.10 어노테이션 (Annotation) (0) 2021.09.09 자바 네트워크(3) / 숫자 야구 게임 (0) 2021.09.09