본문 바로가기
스터디/F-lab

[F-lab] 5주차 정리

by 책 읽는 개발자_테드 2021. 9. 14.
반응형

숙제

  1. Stream.collect 함수에 대해 정리, Stream.Collectors(https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html)에 있는 각종 컬렉터에 대해 정리
  2. Stream을 만들 수 있는 여러가지 방법에 대해 정리
  3. 동시성과 병렬성의 구분
  4. 교착상태(deadlock)이 발생하기 위한 조건과 방지 방법
  5. 스핀락(spinlock)의 정의와 사용 이유 정리
  6. 6. 자바 OutputStream과 Writer의 차이점 / 자바 InputStream과 Reader의 차이점
    7. java.util.Scanner 사용법

1. Stream.collect 함수에 대해 정리

+Stream.Collectors(https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html)에 있는 각종 컬렉터에 대해 정리

 

수집 

· 요소들을 필터링 또는 매핑한 후 요소들을 수집하는 최종 처리 메소드

· 필요한 요소만 컬렉션으로 담거나, 요소들을 그룹핑한 후 집계(리덕션)할 수 있음

· 스트림에서 제공하는 수집 메소드: collect()

 

https://starplatina.tistory.com/entry/Java-8-Stream-API-PART-2

필터링한 요소 수집

· Stream의 collect(Collector<T,A,R> collector) 메소드는 필터링 또는 매핑된 요소들을 새로운 컬렉션에 수집하여 리턴함

리턴 타입 메소드(매개 변수) 인터페이스
R collect(Collector<T,A,R> collector) Stream

· 매개값인 Collector(수집기)는 어떤 요소를 어떤 컬렉션에 수집할 것인지 결정

· Collector의 타입 파타미터 의미: T - 요소, A - 누적기(accumulator) , R - 요소가 저장될 컬렉션

     - T 요소를 A 누적기가 R에 저장한다는 의미

· Collector의 구현 객체는 Collectors 클래스의 정적 메소드를 이용해 얻을 수 있음

리턴 타입 Collectors의 정적 메소드 설명
Collector<T,?,List<T>> toList() T를 List에 저장
Collector<T,?,Set<T>> toSet() T를 Set에 저장
Collector<T,?,Collection<T>> toCollectio(
Supplier<Collection<T>>)
T를 Supplier가 제공한 Collection에 저장
Collector<T,?,Map<K,U>> toMap(
Function<T,K> keyMapper,
Function<T,U> valueMapper)
T를 K와 U로 매핑해서 K를 키로 U를 Map에 저장
Collector<T,?,
ConcurrentMap<K,U>>
toConcurrentMap(
Function<T,K> keyMapper,
Function<T,U> valueMapper)
T를 K와 U로 매핑해서 K를 키로 U를 ConcurrentMap에 저장

· 리턴 타입의 Collector의 A가 ?로 되어 있는 이유: Collector가 R(컬렉션)에 T(요소)에를 저장하는 방법을 알고 있어 A(누적기)가 필요 없기 때문이다.

· ConcurrentMap은 스레드에 안전, Map은 스레드에 안전 x

     - 멀티 스레드 환경에서 ConcurrentMap 이용 권장

 

 예시 - 야채 색상별로 서로 다른 자료구조에 저장하기 

import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CollectDemo {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",Vegetable.Color.GREEN),
                new Vegetable("tomato", Vegetable.Color.RED),
                new Vegetable("redPepper",Vegetable.Color.RED),
                new Vegetable("cabbage",Vegetable.Color.GREEN),
                new Vegetable("eggplant",Vegetable.Color.PURPLE)
        );

        // 초록색 야채를 List 자료구조에 저장
        Stream<Vegetable> greenVegetableStream = vegetables.stream()
                .filter(s->s.getColor()==Vegetable.Color.GREEN);
        Collector<Vegetable, ?, List<Vegetable>> collector = Collectors.toList();
        List <Vegetable> greenVegetables = greenVegetableStream.collect(collector);

        // 빨간색 야채를 HashSet 자료구조에 저장
        Stream<Vegetable> redVegetableStream = vegetables.stream()
                .filter(s->s.getColor()==Vegetable.Color.RED);
        Supplier<HashSet<Vegetable>> supplier = HashSet::new;
        Collector<Vegetable, ?, HashSet<Vegetable>> collector2 = Collectors.toCollection(supplier);
        Set <Vegetable> redVegetables = redVegetableStream.collect(collector2);

        greenVegetables.stream().forEach(vegetable-> System.out.println(vegetable.getName()));
        System.out.println();
        redVegetables.stream().forEach(vegetable-> System.out.println(vegetable.getName()));
    }
    public static class Vegetable{
        public enum Color {GREEN, RED,PURPLE}

        String name;
        Color color;

        Vegetable(String name, Color color){
            this.name = name;
            this.color = color;
        }
        String getName(){
            return name;
        }
        Color getColor(){
            return color;
        }
    }
}

결과

위 코드에서 변수를 생량하여 다음과 같이 간단하게 작성할 수 있다.

public class CollectDemo {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",Vegetable.Color.GREEN),
                new Vegetable("tomato", Vegetable.Color.RED),
                new Vegetable("redPepper",Vegetable.Color.RED),
                new Vegetable("cabbage",Vegetable.Color.GREEN),
                new Vegetable("eggplant",Vegetable.Color.PURPLE)
        );
        
        // 초록색 야채를 List 자료구조에 저장
        List <Vegetable> greenVegetables = vegetables.stream()
                .filter(s->s.getColor()==Vegetable.Color.GREEN)
                .collect(Collectors.toList());
                
        // 빨간색 야채를 HashSet 자료구조에 저장
        Set<Vegetable> redVegetables = vegetables.stream()
                .filter(s->s.getColor()==Vegetable.Color.RED)
                .collect(Collectors.toCollection(HashSet::new));

        greenVegetables.stream().forEach(vegetable-> System.out.println(vegetable.getName()));
        System.out.println();
        redVegetables.stream().forEach(vegetable-> System.out.println(vegetable.getName()));
    }
    public static class Vegetable{
        public enum Color {GREEN, RED,PURPLE}

        String name;
        Color color;

        Vegetable(String name, Color color){
            this.name = name;
            this.color = color;
        }
        String getName(){
            return name;
        }
        Color getColor(){
            return color;
        }
    }
}

 

사용자 정의 컨테이너에 수집

· List, Set, Map과 같은 컬렉션이 아니라 사용자 정의 컨테이너 객체에 수집하는 방법

· 스트림에서는 필터링, 매핑해서 사용자 정의 컨테이너 객체에 수집할 수 있는 collect() 메소드를 추가적으로 제공

인터페이스 리턴 타입 메소드(매개 변수)
Stream R Collect(Supplier<R>, BiConsumer<R,? super T>, BiConsumer<R,R>)
IntStream R Collect(Supplier<R>, ObjIntConsumer<R>, BiConsumer<R,R>)
LongStream R Collect(Supplier<R>, ObjLongConsumer<R>, BiConsumer<R,R>)
DoubleStream R Collect(Supplier<R>, ObjDoubleConsumer<R>, BiConsumer<R,R>)

· Supplier: 수집될 컨테이너 객체(R)을 생성하는 역할

     - 순차 처리(싱글 스레드) 스트림에서는 단 한 번 Supplier가 실행되고 하나의 컨테이너 객체를 생성

     - 병렬 처리(멀티 스레드) 스트림에서는 여러 번 Supplier가 실행되고 스레드별로 여러 개의 컨테이너 객체를 생성

· 두 번째 Consumer: 컨테이너 객체(R)에 요소(T)를 수집하는 역할

     - 스트림에서 요소를 컨테이너에 수집할 때마다 실행

· 세 번째 Consumer: 컨테이너 객체(R)를 결합하는 역할

     - 병렬 처리 스트림에서 호출되어 스레드별로 생성된 컨테이너 객체를 결합해서 단 하나의 최종 컨테이너 객체를 완성

     - 순차 처리 스트림에서는 호출되지 않음

 

· 리턴 타입 R: 요소들이 최종 수집된 컨테이너 객체

     - 순차 처리 스트림에서 리턴 객체: 첫 번째 Supllier가 생성한 객체

     - 병렬 처리 스트림에서 리턴 객: 최종 결합된 컨테이너 객체

 

 예시 - GreenVegetable 사용자 컨테이너에 데이터 수집

public class GreenVegetable {
    private List<Vegetable> list; //요소를 저장할 컬렉션

    public GreenVegetable(){
        list = new ArrayList<Vegetable>();
        System.out.println("[" + Thread.currentThread().getName() + "] GreenVegetable()");
    }
    // 매개값으로 받은 Vegetable을 list 필드에 수집
    public void accumulate(Vegetable vegetable){ //요소를 수집하는 메소드
        list.add(vegetable);
        System.out.println("[" + Thread.currentThread().getName() + "] accumulate()");
    }
    // 병렬 처리 스트림을 사용할 때 다른 GreenVegetable과 결합할 목적으로 실행
    public void combine(GreenVegetable other){ 
        list.addAll(other.getList());
        System.out.println("[" + Thread.currentThread().getName() + "] combine()");
    }
    public List<Vegetable> getList(){ //요소가 저장된 컬렉션 리턴
        return list;
    }
}

 

public class UserDefinedContainerCollectDemo {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",Vegetable.Color.GREEN),
                new Vegetable("tomato", Vegetable.Color.RED),
                new Vegetable("redPepper",Vegetable.Color.RED),
                new Vegetable("cabbage",Vegetable.Color.GREEN),
                new Vegetable("eggplant",Vegetable.Color.PURPLE)
        );

        Stream<Vegetable> greenVegetableStream =  vegetables.stream()
                .filter(s->s.getColor() == Vegetable.Color.GREEN);

        Supplier<GreenVegetable> supplier = () -> new GreenVegetable(); //GreenVegetable을 공급하는 supplier 얻기 
        BiConsumer<GreenVegetable, Vegetable> accumulator = (ms, s) -> ms.accumulate(s); //accumulator로 Vegetable을 수집하는 BiConsumer 얻기 
        //두 개의 Greentable을 매개값으로 받아 combin() 메소드로 결합하는 BiConsumer 얻기. 싱글 스레드에서는 사용 x.
        BiConsumer<GreenVegetable, GreenVegetable> combiner = (ms1, ms2)->ms1.combine(ms2); 

        //GreenVegetable 수집
        GreenVegetable greenVegetable = greenVegetableStream.collect(supplier, accumulator, combiner);

        //수집한 GreenVegetable 출력
        greenVegetable.getList().stream()
                .forEach(s->System.out.println(s.getName()));
    }
}

 

결과

위 람다식을 메소드 참조로 변경하면 다음과 같이 간단하게 작성 가능

public class UserDefinedContainerCollectDemo {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",Vegetable.Color.GREEN),
                new Vegetable("tomato", Vegetable.Color.RED),
                new Vegetable("redPepper",Vegetable.Color.RED),
                new Vegetable("cabbage",Vegetable.Color.GREEN),
                new Vegetable("eggplant",Vegetable.Color.PURPLE)
        );

        GreenVegetable greenVegetable = vegetables.stream()
                .filter(s->s.getColor() == Vegetable.Color.GREEN)
                .collect(GreenVegetable :: new, GreenVegetable:: accumulate, GreenVegetable :: combine);

        greenVegetable.getList().stream()
                .forEach(s->System.out.println(s.getName()));
    }
}

 

요소를 그룹핑해서 수집

· collect() 메소드는 요소를 수집하는 기능 이외에 컬렉션 요소들을 그룹핑해서 Map 객체를 생성하는 기능도 제공

· 사용법: collect()를 호출할 때 Collectors groupingBy() 또는 groupingByConcurrent()가 리턴하는 Collector를 매개값으로 대입 

https://steady-coding.tistory.com/318

 예시 - 야채를 색상과 크기로 각각 그룹핑

public class Vegetable{
    public enum Color {GREEN, RED,PURPLE}
    public enum Size {SMALL, MEDIUM, BIG}

    private String name;
    private Color color;
    private Size size;

    Vegetable(String name, Color color, Size size){
        this.name = name;
        this.color = color;
        this.size = size;
    }
    String getName(){
        return name;
    }
    Color getColor(){
        return color;
    }
    Size getSize(){
        return size;
    }
}

 

public class GroupingDemo {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",Vegetable.Color.GREEN, Vegetable.Size.BIG),
                new Vegetable("tomato", Vegetable.Color.RED, Vegetable.Size.MEDIUM),
                new Vegetable("redPepper",Vegetable.Color.RED, Vegetable.Size.SMALL),
                new Vegetable("cabbage",Vegetable.Color.GREEN, Vegetable.Size.BIG),
                new Vegetable("eggplant",Vegetable.Color.PURPLE, Vegetable.Size.MEDIUM)
        );

        Function<Vegetable, Vegetable.Color> classifier = Vegetable :: getColor; //Vegetable을 Vegetable.Color로 매핑하는 Function 얻기
        //Vegetable.Color가 키, 그룹핑된 List<Vegetable>가 값인 Map을 생성하는 Collector를 얻기
        Collector<Vegetable, ?, Map<Vegetable.Color, List<Vegetable>>> collector = Collectors.groupingBy(classifier);
        Map<Vegetable.Color, List<Vegetable>> mapByColor = vegetables.stream().collect(collector); //Stream의 collect() 메소드로 Vegetable를 Vegetable.Color별로 그룹핑해서 Map을 얻음


        System.out.print("초록색 야채:");
        mapByColor.get(Vegetable.Color.GREEN).forEach(s-> System.out.print(s.getName() + " "));
        System.out.println();
        System.out.print("빨간색 야채:");
        mapByColor.get(Vegetable.Color.RED).forEach(s-> System.out.print(s.getName() + " "));
        System.out.println();
        System.out.print("보라색 야채:");
        mapByColor.get(Vegetable.Color.PURPLE).forEach(s-> System.out.print(s.getName() + " "));
        System.out.println();

        Function<Vegetable, Vegetable.Size> classifier2 = Vegetable :: getSize;
        Function<Vegetable, String> mapper = Vegetable::getName;
        Collector<String, ?, List<String>> collector2 = Collectors.toList();
        Collector<Vegetable, ?, List<String>> collector3 = Collectors.mapping(mapper,collector2);
        Collector<Vegetable, ?, Map<Vegetable.Size, List<String>>> collector4 = Collectors.groupingBy(classifier2, collector3);

        //collect()의 매개값으로 groupingBy(Function<T, K> classifier, Collector<T, A, D> collector) 사용
        Map<Vegetable.Size, List<String>> mapBySize = vegetables.stream().collect(collector4);
        
        System.out.print("큰 야채:");
        mapBySize.get(Vegetable.Size.BIG).forEach(s-> System.out.print(s + " "));
        System.out.println();
        System.out.print("중간 야채:");
        mapBySize.get(Vegetable.Size.MEDIUM).forEach(s-> System.out.print(s + " "));
        System.out.println();
        System.out.print("작은 야채:");
        mapBySize.get(Vegetable.Size.SMALL).forEach(s-> System.out.print(s + " "));
        System.out.println();
    }
}

 

결과

 

위 코드의 변수를 생략하면 다음과 같이 간단하게 작성 가능

public class GroupingDemo {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",Vegetable.Color.GREEN, Vegetable.Size.BIG),
                new Vegetable("tomato", Vegetable.Color.RED, Vegetable.Size.MEDIUM),
                new Vegetable("redPepper",Vegetable.Color.RED, Vegetable.Size.SMALL),
                new Vegetable("cabbage",Vegetable.Color.GREEN, Vegetable.Size.BIG),
                new Vegetable("eggplant",Vegetable.Color.PURPLE, Vegetable.Size.MEDIUM)
        );

        Map<Vegetable.Color, List<Vegetable>> mapByColor = vegetables.stream()
                .collect(Collectors.groupingBy(Vegetable :: getColor));


        System.out.print("초록색 야채:");
        mapByColor.get(Vegetable.Color.GREEN).forEach(s-> System.out.print(s.getName() + " "));
        System.out.println();
        System.out.print("빨간색 야채:");
        mapByColor.get(Vegetable.Color.RED).forEach(s-> System.out.print(s.getName() + " "));
        System.out.println();
        System.out.print("보라색 야채:");
        mapByColor.get(Vegetable.Color.PURPLE).forEach(s-> System.out.print(s.getName() + " "));
        System.out.println();


        Map<Vegetable.Size, List<String>> mapBySize = vegetables.stream()
                .collect(
                        Collectors.groupingBy(
                                Vegetable::getSize,
                                Collectors.mapping(Vegetable::getName, Collectors.toList()))
                        );

        System.out.print("큰 야채:");
        mapBySize.get(Vegetable.Size.BIG).forEach(s-> System.out.print(s + " "));
        System.out.println();
        System.out.print("중간 야채:");
        mapBySize.get(Vegetable.Size.MEDIUM).forEach(s-> System.out.print(s + " "));
        System.out.println();
        System.out.print("작은 야채:");
        mapBySize.get(Vegetable.Size.SMALL).forEach(s-> System.out.print(s + " "));
        System.out.println();
    }
}

 

그룹핑 후 매핑 및 집계

· Collectors.groupingBy() 메소드는 그룹핑 후 매핑이나 집계(평균, 카운팅, 연결, 최대, 최소, 합계)를 할 수 있도록 두 번째 매개값으로 Collector를 가질 수 있음

· Collectors는 매핑과 집계를 위한 Collector를 리턴하는 다양한 메소드를 제공(아래) 

리턴 타입 메소드(매개 변수) 설명
Collector<T, ?, R> mapping(Function<T, U> mapper, Collector<U, A, R> collector> T를 U로 매핑한 후, U를 R에 수집
Collector<T, ?, Double> averagingDouble(ToDoubleFunction<T> mapper) T를 Double로 매핑한 후, Double의 평균값을 산출
Collector<T, ?, Long> counting() T의 카운팅 수를 산출
Collector<CharSequence, ?, String> joining(CharSequence delimiter) CharSequence를 구분자로 연결한 String을 산출
Collector<T, ?, Optional<T>> maxBy(Comparator<T> comparator) Comparator를 이용해서 최대 T를 산출
Collector<T, ?, Optional<T>> minBy(Comparator<T> comparator) Comparator를 이용해서 최소 T를 산출
Collector<T, ?, Integer> summingInt(ToIntFunction)
summingLong(ToLongFunction)
summingDouble(ToDoubleFunction)
Int, Long, Double 타입의 합계 산출

 예시 - 야채의 색상별 무게의 평균과 이름 얻기

public class Vegetable{
    public enum Color {GREEN, RED,PURPLE}

    private String name;
    private double kg;
    private Color color;

    Vegetable(String name, double kg, Color color){
        this.name = name;
        this.kg = kg;
        this.color = color;
    }
    String getName(){
        return name;
    }
    Color getColor(){
        return color;
    }
    double getKg() { return kg; }
}

 

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class GroupingAndReductionExample {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",0.3,Vegetable.Color.GREEN),
                new Vegetable("tomato",0.2, Vegetable.Color.RED),
                new Vegetable("redPepper",0.1,Vegetable.Color.RED),
                new Vegetable("cabbage",2.0,Vegetable.Color.GREEN),
                new Vegetable("eggplant",0.5,Vegetable.Color.PURPLE)
        );

        //1. 그룹핑 절차 그대로 보여주기 
        //야채의 색상별 평균 무게를 저장하는 Map 얻기
        Function<Vegetable, Vegetable.Color> classifier = Vegetable :: getColor;
        ToDoubleFunction<Vegetable> mapper = Vegetable::getKg;
        Collector<Vegetable, ?, Double> collector1 = Collectors.averagingDouble(mapper);
        Collector<Vegetable, ?, Map<Vegetable.Color, Double>> collector2 = Collectors.groupingBy(classifier, collector1);
        Map<Vegetable.Color, Double> mapByColor = vegetables.stream().collect(collector2);

        System.out.println("초록색 야채 전체 평균:" + mapByColor.get(Vegetable.Color.GREEN));
        System.out.println("빨간색 야채 전체 평균:" + mapByColor.get(Vegetable.Color.RED));
        System.out.println("보라색 야채 전체 평균:" + mapByColor.get(Vegetable.Color.PURPLE));

        //2. 변수 생략으로 간단하게 표현하기 
        //야채의 색상을 쉽표로 구분한 이름을 저장하는 Map 얻기
        Map<Vegetable.Color, String> mapByName = vegetables.stream()
                .collect(
                        Collectors.groupingBy(
                                Vegetable :: getColor,
                                Collectors.mapping(Vegetable :: getName, Collectors.joining(","))
                        )
                );

        System.out.println("초록색 야채 전체 이름:" + mapByName.get(Vegetable.Color.GREEN));
        System.out.println("빨간색 야채 전체 이름:" + mapByName.get(Vegetable.Color.RED));
        System.out.println("보라색 야채 전체 이름:" + mapByName.get(Vegetable.Color.PURPLE));
    }
}

위 코드의 변수를 생략하면 다음과 같이 간단하게 작성 가능

public class GroupingAndReductionExample {
    public static void main(String[] args){
        List<Vegetable> vegetables = Arrays.asList(
                new Vegetable("broccoli",0.3,Vegetable.Color.GREEN),
                new Vegetable("tomato",0.2, Vegetable.Color.RED),
                new Vegetable("redPepper",0.1,Vegetable.Color.RED),
                new Vegetable("cabbage",2.0,Vegetable.Color.GREEN),
                new Vegetable("eggplant",0.5,Vegetable.Color.PURPLE)
        );

        //야채의 색상별 평균 무게를 저장하는 Map 얻기
        Map<Vegetable.Color, Double> mapByColor = vegetables.stream()
                .collect(
                        Collectors.groupingBy(
                                Vegetable :: getColor,
                                Collectors.averagingDouble(Vegetable :: getKg)
                        )
                );

        System.out.println("초록색 야채 전체 평균:" + mapByColor.get(Vegetable.Color.GREEN));
        System.out.println("빨간색 야채 전체 평균:" + mapByColor.get(Vegetable.Color.RED));
        System.out.println("보라색 야채 전체 평균:" + mapByColor.get(Vegetable.Color.PURPLE));

        //야채의 색상을 쉽표로 구분한 이름을 저장하는 Map 얻기
        Map<Vegetable.Color, String> mapByName = vegetables.stream()
                .collect(
                        Collectors.groupingBy(
                                Vegetable :: getColor,
                                Collectors.mapping(Vegetable :: getName, Collectors.joining(","))
                        )
                );

        System.out.println("초록색 야채 전체 이름:" + mapByName.get(Vegetable.Color.GREEN));
        System.out.println("빨간색 야채 전체 이름:" + mapByName.get(Vegetable.Color.RED));
        System.out.println("보라색 야채 전체 이름:" + mapByName.get(Vegetable.Color.PURPLE));
    }
}

 

2. Stream을 만들 수 있는 여러가지 방법에 대해 정리

스트림 구현 객체를 얻기 위한 메소드

리턴 타입 메소드(매개 변수) 소스
Stream<T> java.util.Collection.stream()
java.util.Collection.parallelStream()
컬렉션
Stream<T>
IntStream
LongStream
DoubleStream
Arrays.stream(T[]),             Stream.of(T[])
Arrays.stream(int []),          IntStream.of(int[])
Arrays.stream(long[]),        LongStream.of(long[])
Arrays.stream(double[]),    DoubleStream.of(double[])
배열
IntStream IntStream.range(int, int)
IntStream.rangeClosed(int, int)
int 범위
LongStream LongStream.range(long, long)
LongStream.rangeClose(long, long)
long 범위
Stream<Path> Files.find(Path, int, BiPredicate, FileVisitOption)
Files.list(Path)
디렉토리
Stream<String> Files.line(Path, charset)
BufferedReader.lines()
파일
DoubleStream
IntStream
LongStream
Random.doubles()
Random.ints()
Random.longs()
랜덤 수

컬렉션에서 스트림 얻기

 

List<String> list = Arrays.asList("tester1","tester2","tester3");
    Stream<String> stream = list.stream();
        stream.forEach(name -> System.out.println(name));

 

배열에서 스트림 얻기

 

String[] vegetables = {"broccoli","tomato","cabbage"};
Stream<String> stream = Arrays.stream(vegetables);
    stream.forEach(s-> System.out.println(s))

 

숫자 범위에서 스트림 얻기

 

IntStream intStream = IntStream.rangeClosed(1,100);
intStream.forEach(i -> System.out.println(i)); //1부터 100까지 출력

 

파일에서 스트림 얻기

· Files와 BufferedReader의 lines() 메소드를 이용하여 문자 파일의 내용을 스트림을 통해 행 단위로 읽고 콘솔에 출력

 

Path path = Paths.get("/Users/ted.sc/Desktop/java8.txt");
Stream<String> stream;
    
    //1. Filses.lines() 메소드 이용
    stream = Files.lines(path, Charset.defaultCharset()); //운영체제의 기본 문자셋
    stream.forEach(System.out::println); //메소드 참조, (s->System.out.println(s))과 동일
    
    //2. BufferedReader의 lines() 메소드 이용
    File file = path.toFile();
    FileReader fileReader = new FileReader(file);
    BufferedReader br = new BufferedReader(fileReader);
    stream = br.lines();
    stream.forEach(System.out::println);

 

결과

 

디렉토리에서 스트림 얻기

 

Path path = Paths.get("/Users/ted.sc/Desktop");
Stream<Path> stream = Files.list(path); //서브 디렉토리, 파일 목록을 스트림에 입력
    stream.forEach(System.out::println);

 

3. 동시성과 병렬성의 구분

· 동시성(Concurrency): 두 개 이상의 작업이 겹치는 시간에 시작, 실행, 완료 되는 것이다. 단, 여러 작업이 반드시 동일한 순간에 실행되는 것은 아니다. ex) 단일 코어 시분할 방식

· 병렬성(Parallelism): 두 개 이상의 스레드가 동시에 실행되는 것이다.

 

https://devopedia.org/concurrency-vs-parallelism

 

 

출처

https://stackoverflow.com/questions/1050222/what-is-the-difference-between-concurrency-and-parallelism

https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032b/index.html

 

4. 교착상태(deadlock)가 발생하기 위한 조건과 방지 방법

https://scshim.tistory.com/382

 

5. 스핀락(spinlock)의 정의와 사용 이유 정리

https://scshim.tistory.com/manage/posts/

 

6. 자바 OutputStream과 Writer의 차이점 / 자바 InputStream과 Reader의 차이점

OutputStream

· 바이트 기반 입력 스트림의 최상위 클래스(추상 클래스)

· byte 자료형으로 데이터를 출력

· 모든 바이트 기반 출력 스트림은 이 클래스를 상속(FileOutputStream, BufferedOutputStream, DataOutputStream)

· 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 읽을 수 있음

 

Writer

· 문자 기반 입력 스트림의 최상위 클래스(추상 클래스)

· char 자료형으로 데이터를 출력

· 모든 문자 기반 출력 스트림은 이 클래스를 상속(FileWriter, BufferedWriter, PrintWriter, OutputStreamWriter)

· 문자 데이터를 읽는 데 특화

 

InputStream

· 바이트 기반 입력 스트림의 최상위 클래스(추상 클래스)

· byte 자료형으로 데이터를 입력

· 모든 바이트 기반 출력 스트림은 이 클래스를 상속(FileInputStream, BufferedInputStream, DataInputStream)

· 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 읽을 수 있음

 

Reader

· 문자 기반 입력 스트림의 최상위 클래스(추상 클래스)

· char 자료형으로 데이터를 입력

· 모든 문자 기반 입력 스트림은 이 클래스를 상속(FileReader. BufferedReader, InputStreamReader)

· 문자 데이터를 읽는 데 특화


7. java.util.Scanner 사용법

https://scshim.tistory.com/281

반응형

'스터디 > F-lab' 카테고리의 다른 글

[F-lab] 7주차 정리 - 웹 프로그래밍 기초와 JSP  (0) 2021.10.07
[F-lab] 3주차 정리_자바  (0) 2021.08.31
[F-lab] 2주차 정리_자바  (0) 2021.08.24

댓글