728x90
    
    
  반응형
    
    
    
  - Operator : 매개 변수 0, 리턴0 (연산 결과)
- 연산하는 것
- Function의 하위 인터페이스로 보통 매개변수값을 연산하고 그 결과를 리턴하는 경우 사용
 BinaryOperator<T> T apply(T t1, T t2) UnaryOperator<T> T apply(T t) xxxBinaryOperator xxx applyAsXXX(xxx,xxx) xxxUnaryOperator xxx applyAsXXX(xxx) 
- predicate : 매개 변수 0, 리턴0 (boolean), 추상 메서드를 test라는 이름으로 가지고 있따.인터페이스 리턴(boolean)
Predicate<T> boolean test(T t) BiPredicate boolean test(T t, U u) xxxPredicate boolean test(xxxx) 
Stream
- 스트림 : 여러 값들을 가지고 있는 배열이나 컬렉션등을 for문이 아닌 함수형 인터페이스를 이용해서 반복 처리할 수 있는 기능
- 필수는 아니지만 가독성 좋은 코드를 생성하기 위해서 알아둬야 함.
- 스트림 객체 생성 : build() 메서드 이용하기
- builder()메서드로 Builder 객체 생성 이후에 add() 메서드로 리턴타입이 Builder 객체이므로 메서드 체이닝 가능
 
- 스트림 사용 : 배열, 컬렉션, 빌더를 사용할 수 있다.
- generate()메서드 이용하기
- 람다에서 Supplier<T> 인터페이스를 이용하여 값을 추가 생성합니다.
 
- 스트림은 람다(함수형 인터페이스)를 활용하여 내부 반복자를 이용 시간과 코드의 양을 줄임, 또한 스트림을 통해서 간단하게 병렬 처리가 가능
스트림의 처리 단계!
- 생성 : 스트림 인스턴스 생성
- 가공 : 필터링과 맵핑 등 원하는 결과를 만들어가는 중간 작업
- 결과 : 최종적으로 결과를 얻어내는 작업
- 외부 반복자 vs 내부 반복자
- 외부 반복자 : 컬렉션 내의 요소를 반복문을 통해 하나씩 읽어 처리하는 방식 (for문)
- 내부 반복자 : 스트림의 for-each 메서드를 람다식을 사용해서 기술하는 방식을 의미 (stream)
 

- 외부 파일에서 스트림 생성하기
- Files.find(Path, int BiPredicatem FileVisitOption) , Files.list(Path)
- 반환타입 : Stream<Path>
 
- Files.lines(Path, Charset), BufferedReader.lines()
- 반환타입 : Stream<String>
 
 
- Files.find(Path, int BiPredicatem FileVisitOption) , Files.list(Path)
package G_java;
import java.util.stream.Stream;
import java.util.Arrays;
import java.util.List;
public class G08_StreamEx {
    public static void main(String[] args) {
        //배열을 이용한 스트림 생성
        String[] arr = new String[]{
            "a", "b", "c", "d","e","f"
        };
        Stream<String> stream1 = Arrays.stream(arr);
        stream1.forEach(s->System.out.print(s+" "));
        System.out.println();
        Stream<String> stream2 = Arrays.stream(arr, 2, 5); //배열의 일부를 추출해서 객체 생성
        stream2.forEach(s->System.out.print(s+" "));
        System.out.println();
        //문자열 배열을 컬렉션 프레임워크로 만들어서 스트림 만들기
        List<String> list = Arrays.asList(arr);
        //List 객체를 stream()를 이용. Stream 객체 생성
        Stream<String> stream3 = list.stream();
        stream3.forEach(s->System.out.print(s));
        //스트림 객체 생성 : build() 메서드 이용하기
        Stream stream4 = Stream.builder() //집어넣는 개수에 따라서 달라짐!! 따로 limit이 필요치 않다!
            .add("무궁화")
            .add("삼천리")
            .add("화려강산")
            .add("대한사람")
            .add("현영이")
            .build();
        stream4.forEach(s->System.out.println(s+" "));
        System.out.println();
        //스트림 객체 생성 : 2.generate()메서드 이용하기
        //람다에서 Supplier<T> 인터페이스를 이용하여 값을 추가 생성합니다.
        Stream<String> Stream5 = Stream.generate(()->"애국가").limit(10); //limit이 없으면 끝이 안난다.
        Stream5.forEach(s->System.out.println(s+" "));
        //스트림 객체 생성 : 3. iterate() 메서드 이용하기
        Stream<Integer> stream6 = Stream.iterate(1, n->n+1).limit(10);  //시작 값 1->10까지
        stream6.forEach(s-> System.out.println(s+" "));
    }
}
가공단계
- 가공 중간 처리 단계
- 필터링 : filtering
- Stream 내의 요소를 걸러내는 기능을 말함
- 메소드
- distinct() : 중복 제거
- filter() : 조건에 맞는 요소를 선택(boolean 결과에 따른 검출)
 
- Stream
- Steam
- IntStream
- LongStream
- DoubleStream
 
 
package G_java;
import java.util.Arrays;
import java.util.List;
public class G11_FilteringEx {
    public static void main(String[] args) {
        //list 객체 생성하기
        List<String> list = Arrays.asList("홍길동", "김유신","홍길동", "이순신 ","홍길동", "유관순","홍길동", "김유신" );
        //distinct() 메소드로 중복 제거 후 내부 반복자로 출력
        System.out.println("distinct()");
        list.stream().distinct().forEach(s->System.out.println(s+" "));
        System.out.println();
        //"홍으로 시작하는 문자열로 필터링 후 내부 반복자로 출력
        System.out.println("filter()");
        list.stream().filter(n->n.startsWith("홍"))
            .forEach(e->System.out.println(e+" "));
        //distinct()와 filter()를 동시에 사용
        System.out.println("distinct()+filter()");
        list.stream().distinct().filter(n->n.startsWith("홍")).forEach(e->System.out.println(e+" "));
    }
}
- 매핑 : mapping 연결해줌
- 컬렉션 프레임워크에 맵과 유사한 기능을 한다. 즉, key: value와 같이 묶어주는 것을 맵핑이라고 한다.
- 맵핑은 스트림의 데이터를 매개변수로 받아서 가공처리 후 새로운 스트림을 만들어 리턴한다.
- 데이터 변환을 위한 기능
- 메서드
- flatMapXXX() 메서드
- 다른 타입의 요소를 가진 스트림을 생성 및 반환
- 리턴 타입
- Stream <R>
- DoubleStream
- IntStream
- LongStream
 
 
- mapXXX()
- asDoubleStream()
- asLongStream()
- box()
 
- flatMapXXX() 메서드
 
package G_java;
import java.util.Arrays;
import java.util.List;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
public class G12_mappingEx {
    public static void main(String[] args) {
        //flatMapXXX() 메서드
        //문자열을 공백으로 분리해서 매핑
        List<String> list1 = Arrays.asList("동백물과", "백두산이", "마르고 닳도록");
        list1.stream().flatMap(data -> Arrays.stream(data.split(" "))).forEach(word->System.out.println(word));
        //문자열을 , 로 분리해서 double 자료형으로 반환하여 맵핑
        List<String> list2 = Arrays.asList("1.1,2.2,3.3","4.4,5.5,6.6"); //이걸 더블 스트링으로 바꿀거에용
        DoubleStream dsr = list2.stream().flatMapToDouble(data->{
            String[] strArr = data.split(",");
            double[] dArr = new double[strArr.length];
            for (int i = 0;i<dArr.length;i++){
                dArr[i] = Double.parseDouble(strArr[i].trim());
            }
            return Arrays.stream(dArr);
        });
        dsr.forEach(n-> System.out.println(n));
        System.out.println();
        //---------------------여기부터 공부 다시 하기------------------
        //문자열을 , 로 분리해서 int 자료형으로 변화해서 매핑
        List<String> list3 = Arrays.asList("1, 2, 3","4, 5, 6");
        IntStream isr = list3.stream().flatMapToInt(data -> {
            String[] strArr = data.split(",");
            int[] intArr = new int[strArr.length];
            for(int i = 0; i< strArr.length; i++) {
                intArr[i] = Integer.parseInt(strArr[i].trim());
            }
            return Arrays.stream(intArr);
        });
        isr.forEach(s -> System.out.println(s));
        //mapXXX() 메서드 : 요소를 새로 구성해서 새로운 스트림을 리턴
        List<String> list4 = Arrays.asList("동해물과", "백두산이","마르고 닳도록");
        System.out.println("함수적 인터페이스 방식");
        list4.stream().mapToInt(String::length)
            .forEach(len -> System.out.println(len));
        // - asDoubleStream, asLongStream, boxed
        // asDoubleStream : IntStream, LongStream을 DoubleStream으로 형변환
        // asLongStream : IntStream을 LongStream으로 형변환
        // boxed : IntStream, LongStream, DoubleStream을 각가 Stream<Integer>
        //     , Stream<Long>, Stream<Double>로 형변환
        int intArr[] = {10, 20, 30, 40, 50, 60};
        // double타입의 요소를 갖는 DoubleStream으로 형변환
        Arrays.stream(intArr).asDoubleStream()
                        .forEach(d -> System.out.println(d));
        System.out.println();
        //int타입의 요소를 갖는  Stream<Integer>으로 형변환
        Arrays.stream(intArr).boxed()
                        .forEach(i -> System.out.println(i.getClass()));
    }
}
- 정렬 : sorting
package G_java;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class G13_SortingEx {
    public static void main(String[] args) {
            /*
     *  Stream의 중간 단계에서 sorted메서드를 사용하여 순서를 변경할 수 있음. 
     *  일반적인 객체를 정렬하기 위해서는 Comparable 인터페이스를 구현한 클래스 객체만 정렬
     *  가능합니다. 
     * 
     */
     List<String> list = Arrays.asList("홍길동", "김유신","이순신","유관순");
     System.out.println("기본 정렬");
     list.stream().sorted().forEach(System.out::println);  // 메서드 참조 방식
     System.out.println();
     System.out.println("역순 정렬");
     list.stream().sorted(Comparator.reverseOrder())
                           .forEach(System.out::println);  // 메서드 참조 방식
     System.out.println();
     //일반 객체 정렬 테스트
     Shape s1 = new Rectangle(10, 3);
     Shape s2 = new Circle(10);
     Shape s3 = new Rectangle(20, 2);
     Shape s4 = new Circle(11);
     List<Shape> list2 = Arrays.asList(s1, s2, s3, s4);
     System.out.println("오름차순 정렬");
     list2.stream().sorted().forEach(System.out::println);
     System.out.println("내림차순 정렬");
     list2.stream().sorted((a, b) -> b.compareTo(a) - a.compareTo(b))
                 .forEach(System.out::println);
     System.out.println("내림차순 정렬2");
     list2.stream().sorted(Comparator.reverseOrder())
                 .forEach(System.out::println);
        // 둘레를 기준으로 정렬
        System.out.println("정렬하지 않고 출력");
        list2.stream().forEach(System.out::println);
        System.out.println("둘레(length()) 순으로 정렬");
        System.out.println("함수적 인터페이스로 구현");
        list2.stream().sorted(new Comparator<Shape>() {
            public int compare(Shape o1, Shape o2) {
                return (int)(o1.length() - o2.length());
            };
        }).forEach(System.out::println);
        System.out.println("람다표현식을 이용해서 둘레순으로 정렬");
        list2.stream().sorted((a,b) -> (int)(b.length() - a.length()))
                    .forEach(System.out::println);
    }
}
abstract class Shape implements Comparable<Shape> {
    //필드
    int x, y;
    //생성자
    Shape() {
        this(0, 0);
    }
    Shape(int x, int y) {
        this.x = x;
        this.y = y;
    }
    //추상 메서드
    abstract double area();
    abstract double length();
    //일반 메서드
    public String getLocation() {
        return "x: "+x+", y: "+y;
    }
    @Override
    public int compareTo(Shape o) {
        return (int)(this.area() - o.area());
    }
}
class Rectangle extends Shape {
    // 필드
    int w, h;
    //생성자
    public Rectangle() {
        this(1, 1);
    }
    public Rectangle(int w, int h) {
        this.w = w;
        this.h = h;
    }
    @Override
    double area() {
        return (w*h);
    }
    @Override
    double length() {
        return (w+h) * 2;
    }
    @Override
    public String toString() {
        return "넓이 : "+this.area();
    }
}
class Circle extends Shape {
    //필드 
    double r;
    //생성자 
    public Circle() {
        this(1);
    }
    public Circle(double r) {
        this.r = r;
    }
    @Override
    double area() {
        return (r * r) * Math.PI;
    }
    @Override
    double length() {
        return (r * 2) * Math.PI;
    }
    @Override
    public String toString() {
        return "넓이는 : "+this.area();
    }
}
- 그룹핑 : grouping
package G_java;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class G17_collect_groupBy {
    // collect() 메서드는 스트림의 요소들을 필터링하거 매핑한 후에 새로운 객체로 생성
    // groupingBy() 메서드는 Map객체를 생성할 수 있습니다. 
    public static void main(String[] args) {
        Shape s1 = new Rectangle(10, 3);
        Shape s2 = new Circle(10);
        Shape s3 = new Rectangle(20, 2);
        Shape s4 = new Circle(11);
        List<Shape> list = Arrays.asList(s1, s2, s3, s4);
        //요소가 Rectangle 객체인 경우 collect 메서드로 List로 변환
        List<Shape> rectList = list.stream()
                .filter(s -> s instanceof Rectangle).collect(Collectors.toList());
        rectList.stream().forEach(f -> System.out.println(f));
        System.out.println();
        // 요소가 Rectangle 객체인 경우 collect 메서드로 Set으로 변환
        Set<Shape> rectSet = list.stream()
             .filter(s -> s instanceof Rectangle).collect(Collectors.toSet());
        rectSet.stream().forEach(System.out::println); //메소드 접근 방법 -> 하나의 값을 넘겼을 때 그 함수 값을 실행시키세요!
        //groupingBy() Map 객체 생성
        //key-value 값으로 정의
        try {
            // 객체 타입으로 그룹핑 (Rectangle, Circle)
            Map<Object, List<Shape>> map = list.stream() //obj -> 객체
                .collect(Collectors.groupingBy(f -> f.getClass()));
            System.out.println("사각형 출력");
            map.get(Class.forName("Rectangle")).stream()
                    .forEach(f -> System.out.println(f));
            map.get(Class.forName("Circle")).stream()
                    .forEach(f -> System.out.println(f));
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
728x90
    
    
  반응형
    
    
    
  '개발 언어 > JAVA' 카테고리의 다른 글
| 17. Network, 서버 만들기! (0) | 2024.03.28 | 
|---|---|
| 16. ParallelStream, Thread (0) | 2024.03.27 | 
| 14 람다식 (0) | 2024.03.25 | 
| 13 객체 정렬을 위한 객체 간 크기 비교, 제너릭 , File 입출력 (0) | 2024.03.21 | 
| 12 JAVA API (0) | 2024.03.20 | 
