본문 바로가기

Java/Java 알고리즘 2

[Java 알고리즘] (5) 스트림 생성과 중간연산

반응형

1. Function과 Predicate

2. 정렬과 IntStream의 수학 메서드

3.map()을 통한 다양한 변환

4. 스트림의 스트림 -> 스트림으로 변환


 

1. Function과 Predicate

package lamdaAndstream;

import java.util.function.*;
import java.util.*;

class FunctionAndPredicate {
    public static void main(String[] args) {
        Supplier<Integer>  x = ()-> (int)(Math.random()*100)+1;
        Consumer<Integer>  c = i -> System.out.print(i+", ");
        Predicate<Integer> z = i -> i%2==0;
        Function<Integer, Integer> k = i -> i/10*10; // i의 일의 자리를 없앤다.


        Function<String, Integer>	f  = (s) -> Integer.parseInt(s, 16);
        Function<Integer, String>	g  = (i) -> Integer.toBinaryString(i);

        Function<String, String>	h  = f.andThen(g);
        Function<Integer, Integer>  h2 = f.compose(g);

        System.out.println(h.apply("FF")); // "FF" → 255 → "11111111"
        System.out.println(h2.apply(2));   // 2 → "10" → 16


        Function<String, String> f2 = w -> w; // 항등 함수(identity function)
        System.out.println(f2.apply("AAA"));  // AAA가 그대로 출력됨

        Predicate<Integer> p = i -> i < 100;
        Predicate<Integer> q = i -> i < 200;
        Predicate<Integer> r = i -> i%2 == 0;
        Predicate<Integer> notP = p.negate(); // i >= 100

        Predicate<Integer> all = notP.and(q).or(r);
        System.out.println(all.test(150));       // true

        String str1 = "abc";
        String str2 = "abc";

        // str1과 str2가 같은지 비교한 결과를 반환
        Predicate<String> p2 = Predicate.isEqual(str1);
        boolean result = p2.test(str2);
        System.out.println(result);
        
        
        List<Integer> list = new ArrayList<>();
        makeRandomList(x, list);
        System.out.println(list);
        printEvenNum(z, c, list);
        List<Integer> newList = doSomething(k, list);
        System.out.println(newList);
    }

    static <T> List<T> doSomething(Function<T, T> k, List<T> list) {
        List<T> newList = new ArrayList<T>(list.size());

        for(T i : list) {
            newList.add(k.apply(i));
        }

        return newList;
    }

    static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
        System.out.print("[");
        for(T i : list) {
            if(p.test(i))
                c.accept(i);
        }
        System.out.println("]");
    }

    static <T> void makeRandomList(Supplier<T> x, List<T> list) {
        for(int i=0;i<10;i++) {
            list.add(x.get());
        }
    }
}

 

 

2. 정렬과 IntStream의 수학 메서드

package lamdaAndstream;

import java.util.Comparator;
import java.util.stream.Stream;

public class Stream1 {

        public static void main(String[] args) {
            Stream<Student> studentStream = Stream.of(
                    new Student("이자바", 3, 300),
                    new Student("김자바", 1, 200),
                    new Student("안자바", 2, 100),
                    new Student("박자바", 2, 150),
                    new Student("소자바", 1, 200),
                    new Student("나자바", 3, 290),
                    new Student("감자바", 3, 180)
            );

            //1. 반별 정렬, 기본 정렬을 이용한 스트림 생성

            //2. IntStream의 수학 메서드 이용 / 스트림의 통계정보 이용
        }
    }

    class Student implements Comparable<Student> {
        String name;
        int ban;
        int totalScore;

        Student(String name, int ban, int totalScore) {
            this.name =name;
            this.ban =ban;
            this.totalScore =totalScore;
        }

        public String toString() {
            return String.format("[%s, %d, %d]", name, ban, totalScore).toString();
        }

        String getName()     { return name;}
        int getBan()         { return ban;}
        int getTotalScore()  { return totalScore;}

        // 총점 내림차순을 기본 정렬로 한다.
        public int compareTo(Student s) {
            return s.totalScore - this.totalScore;
        }
    }

 

//1. 반별 정렬, 기본 정렬을 이용한 스트림 생성

studentStream.sorted(Comparator.comparing(Student::getBan) // 반별 정렬
     .thenComparing(Comparator.naturalOrder()))    // 기본 정렬
 .forEach(System.out::println);
 
 
 
//2. IntStream의 수학 메서드 이용 / 스트림의 통계정보 이용
Stream<Student> stuStream = Stream.of(stuArr);

		stuStream.sorted(Comparator.comparing(Student::getBan)
				 .thenComparing(Comparator.naturalOrder()))
				 .forEach(System.out::println);

		stuStream = Stream.of(stuArr); // 스트림을 다시 생성한다. 
	        IntStream stuScoreStream= stuStream.mapToInt(Student::getTotalScore);

		IntSummaryStatistics stat = stuScoreStream.summaryStatistics();
		System.out.println("count="+stat.getCount());
		System.out.println("sum="+stat.getSum());
		System.out.printf("average=%.2f%n", stat.getAverage());
		System.out.println("min="+stat.getMin());
		System.out.println("max="+stat.getMax());

 

 

3.map()을 통한 다양한 변환

package lamdaAndstream;

import java.io.File;
import java.util.stream.Stream;

public class Stream2 {
        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);
            filenameStream.forEach(System.out::println); // 모든 파일의 이름을 출력

            fileStream = Stream.of(fileArr);  // 스트림을 다시 생성

            //스트림을 이용한 변환
            // 1. Stream<File> → Stream<String>
            // 2. 확장자가 없는 것은 제외
            // 3. 확장자만 추출
            // 4. 모두 대문자로 변환
            // 5. 중복 제거
            // 6. JAVABAKTXT	

            System.out.println();
        }
    }

 

fileStream.map(File::getName)          // Stream<File> → Stream<String>
         .filter(s -> s.indexOf('.')!=-1)   // 확장자가 없는 것은 제외
         .map(s -> s.substring(s.indexOf('.')+1)) // 확장자만 추출
         .map(String::toUpperCase)    // 모두 대문자로 변환
         .distinct()               //  중복 제거
         .forEach(System.out::print); // JAVABAKTXT   

 

 

 

4. 스트림의 스트림 -> 스트림으로 변환

package lamdaAndstream;

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

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

            Stream<String[]> strArrStrm = Stream.of(
                    new String[]{"abc", "def", "jkl"},
                    new String[]{"ABC", "GHI", "JKL"}
            );
            //스트림 생성해
            //1. 소문자 만들기
            //2. 중복 제거
            //3. 정렬
            //4. 출력
            

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

            //스트림 생성해
            //1. 소문자 만들기
            //2. 중복 제거
            //3. 정렬
            //4. 출력

            Stream<String> strStrm1 = Stream.of("AAA", "ABC", "bBb", "Dd");
            Stream<String> strStrm2 = Stream.of("bbb", "aaa", "ccc", "dd");
            
            //두 개의 스트림을 합쳐서 스트림의 스트림 생성
            //1. 문자열 배열 스트림으로 변환
            //2. 스트림의 스트림을 문자열 스트림으로 변환
            
            //스트림 재 생성
            //1. 소문자 만들기
            //2. 중복 제거
            //3. 정렬
            //4. 출력
        }
    }

 

	//1.

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

      strStrm.map(String::toLowerCase)
            .distinct()
            .sorted()
            .forEach(System.out::println);


	//2.
    Stream<String> lineStream = Arrays.stream(lineArr);
		lineStream.flatMap(line -> Stream.of(line.split(" +")))
				  .map(String::toLowerCase)
				  .distinct()
				  .sorted()
				  .forEach(System.out::println);


     //3.
     Stream<Stream<String>> strStrmStrm = Stream.of(strStrm1, strStrm2);

		Stream<String> strStream = strStrmStrm
                                .map(s -> s.toArray(String[]::new))  
                                .flatMap(Arrays::stream);

		strStream.map(String::toLowerCase)
				 .distinct()
				 .forEach(System.out::println);
반응형