스트림

성혜·2024년 1월 22일
0

Java

목록 보기
23/25
post-thumbnail

스트림, Stream

Java 8(1.8) + 람다식과 같이 출시

배열(컬렉션)의 탐색(조작) 기술 => 확실하게 자리 잡은 곳

익명 객체 (적극적으로) 사용 > 람다식 사용 + 함수형 인터페이스

  • 파일 입출력 지원
  • 디렉토리 탐색 지원
  • 기타 등등.. 여러곳에서 시도 중..

💥Data.getStringList(10)와 같은 코드는
이클립스에 여러 데이터을 가져오는 파일을 가져와 사용 중이기 때문에 가능한 코드입니다.

Data.class 등등 

스트림 얻어오는 방법 (stream()메서드)

1. 배열로부터

		int[] nums1 = {10,20,30,40,50};
		Arrays.stream(nums1).forEach(num -> System.out.println(num));

2. 컬렉션으로부터

		ArrayList<Integer> nums2 = new ArrayList<>();
		nums2.add(100);
		nums2.add(200);
		nums2.add(300);
		nums2.stream().forEach(num -> System.out.println(num));
		System.out.println();


3. 숫자 범위

		IntStream.range(1, 10).forEach(num->System.out.println(num));
		System.out.println();

4. 파일 > 읽기 작업만 가능

		try {
			
			//4. 파일 > 읽기 작업만 가능
			Path path = Paths.get("dat\\score.txt");
			Files.lines(path).forEach(str ->System.out.println(str));;
			
			
		} catch (Exception e) {
			System.out.println("Ex68_Stream.m3");
			e.printStackTrace();
		}

5. 디렉토리로부터

		Path dir = Paths.get("C:\\class\\dev\\eclipse");
		Files.list(dir).forEach(p -> {
			System.out.println(p.getFileName());
		});


파이프

: 스트림 객체 메서드

1. 중간 파이프

  • filter(Predicate)
    : 앞의 스트림으로부터 요소를 받아 조건을 맞느 요소만 남기고 맞지 않는 요소는 버림

  • distinct()
    : 앞의 스트림에서 중복 요소를 제거한다.
    : 유일한 요소만 남아있는 스트림을 반환.
    : Set 성질

  • map(Function), mapXXX(Function)
    : 앞의 스트림의 요소를 다른 형태로 변환 후 새로운 스트림을 반환한다.

  • sorted(Comparator)
    : 사용법이 배열, 컬렉션의 sort() 메서드와 동일 > Comparator


2. 최종 파이프

  • forEach(Consumer)
    : 앞의 스트림으로부터 요소를 받아 최종 처리하는 메서드

  • count()
    : 앞의 스트림의 개수를 반환

  • allMatch(), anyMatch(), noneMatch()

    : boolean allMatch(Predicate) : 모든 요소가 조건을 만족하는지?
    : boolean anyMatch(Predicate) : 일부 요소가 조건을 만족하는지?
    : boolean noneMatch(Predicate): 모든 요소가 조건을 불만족하는지?

  • 집계/통계 , Reduce
    : 앞의 스트림의 요소를 취합해서 하나의 통계값을 생성
    : count()
    : max()
    : min()
    : sum()
    : avg()


  • 예시 코드
		//filter에는 true만 남기고 다 버리기 때문에 짝수만 있는 stream을 반환함! 
        //그 다음 파이프를 연결시킴 ! => 그래서 중간 파이프
        
        List<String>list = Data.getStringList(10);
        
		list.stream().filter(n -> {
			if(n % 2 ==0) {
				return true;
			}else {
				return false;
			}
		}).forEach(n -> System.out.printf("%4d",n));
		System.out.println();
        
        
        
        //조건이 여러개
        //하나의 필터에 하나의 조건만 넣은 것이 좋음!
		list.stream()
		.filter(n -> n%2 ==0)
		.filter(n -> n >= 50)
		.forEach(n ->System.out.printf("%4d", n));
		System.out.println();
        

  • 중복값 제거 코드
		//중복값 제거하기
		System.out.println(list.stream().count()); //최종 파이프, 반환값 long 타입/결과 : 100
		System.out.println(list.stream().distinct().count()); //결과 : 61

  • map 중간 파이프 예시 코드
		List<String> list = Data.getStringList(10);
		System.out.println(list);
		System.out.println();
		
		list.stream()
				.map(word -> word.length()) //문자 길이로 변환 한 새로운 stream으로 반환
				.forEach(word -> System.out.println(word)); //이때 word은 문자길이
		//결과 : 6 2 3 2 5 2 2 3 2 ..
		System.out.println();

  • sorted
		//오름차순 정리
		Data.getIntList(10).stream()
							.sorted()
							.forEach(n -> System.out.println(n));
		System.out.println();
		
		//내림차순 정리
		Data.getIntList(10).stream()
							.sorted((a,b) -> b-a)
							.forEach(n -> System.out.println(n));
		System.out.println();
		
		Data.getIntList(10).stream()
							//.sorted(Comparator.naturalOrder())//오름차순
							.sorted(Comparator.reverseOrder()) //내림차순
							.forEach(n -> System.out.println(n));
		System.out.println();

  • allMatch(), anyMatch(), noneMatch()
		result = Data.getUserList()
					.stream()
					.filter(user -> user.getHeight() >=178)
					.allMatch(user -> user.getGender() ==1);
		System.out.println(result); //결과: true

-count(), max(), min()

		//count()
		long count = Data.getIntList().stream().count();
		System.out.println(count);
		
		System.out.println(Data.getUserList().stream().filter(user -> 
		user.getGender() == 1).count()); //7
		
		System.out.println(Data.getUserList().stream().filter(user -> 
		user.getGender() == 2).count()); //3
		
		//max(), min()
		List<Integer> nums = Data.getIntList();
		
		int max = -1; //nums안의 모든 숫자 가장 숫자 -1
		int min = 101; //nums안의 모든 숫자 중 가장 큰 숫자 +1
		
		for(int n : nums) {
			if(n>max) {
				max = n;
			}
			if(n<min) {
				min =n;
			}
		}
		System.out.println(max); //99
		System.out.println(min); //0
		
		//비교 기준 제시
		//Optional<Integer>
		//- Integer or int 타입과 동일한 자료형
		//- 값형은 null을 가질 수 없다.
		//- 참조형은 null을 가질 수 있다. 
		// - null을 가질 수 있는 int
		System.out.println( nums.stream().max((a,b)-> a-b)); //Optional[99]
		
		//만약 max가 없을 때 int는 null값을 가질 수 없다 ! 
		//하지만 null값을 돌려주는게 좋음 =>  optinal 이용
		//int result = nums.stream().max((a,b)-> a-b); //에러
		Optional<Integer> result = nums.stream().max((a,b)-> a-b); //Optional[99]
		
		System.out.println(result.get()); //99
		
		Optional<User> user = Data.getUserList().stream().max((user1, user2) ->
		user1.getHeight() - user2.getHeight());
		
		System.out.println(user.get());
		
		Optional<User> user3 = Data.getUserList().stream().min((user1, user2) ->
		user1.getHeight() - user2.getHeight());
		System.out.println(user3.get());
		
		//스트림 요소 타입 > 숫자o or 숫자x
		//- count(), max(), min() > Stream<Type> > 모든 자료형에 적용 가능
		
		//스트림 요소 타입 > 숫자o
		//- sum(), abg() > IntStream, DoubleStream.. > 숫자 전용 스트림
		
		//nums.stream() == Stream<Integer>
		//nums.stream().mapToInt(n -> n) == IntStream - Integer 전용스트림 반환
		
		//sum은 값이 없어도 0을 무조건 반환 => 반환값이 int
		System.out.println(nums.stream().mapToInt(n -> n).sum()); //결과: 4746
		
		//average는 값이 없으면 반환할 수 없기 때문에 optional값으로 리턴
		OptionalDouble avg= nums.stream().mapToInt(n -> n).average();
		System.out.println(avg.getAsDouble()); //결과: 47.46
		
		// 남자 평균 키?
		double height = Data.getUserList().stream()
							.filter(u -> u.getGender()==1)
							.mapToInt(u -> u.getHeight()) //Stream<User> => Stream<Integer>
							.average()
							.getAsDouble();
						
		System.out.println(height); //결과 : 174.57142857142858
profile
하루를 정리하고 기록합니다.

0개의 댓글