본문 바로가기

TIL

[TIL] 210805

1. Collection
2. Iterator
3. Stream
4. Optional

Collection

  • 여러 데이터의 묶음을 Collection이라고 한다.
  • Collection은 추상체
    • Collection의 구상체 : List, set
      • List의 구상체 : LnkedList, ArrayList, Vector, Stack
      • Set의 구상체 : HashSet

Iterator

  • 여러 데이터의 묶음을 풀어서 하나씩 처리할 수 있는 수단을 제공한다.
  • next()를 통해서 다음 데이터를 조회할 수 있다.
  • 앞 쪽 방향으로 방향을 바꿀 수 없다. --> 이전 데이터 조회 불가

Stream

  • Java 8 이상에서 부터 사용 가능.
  • 데이터의 연속을 나타냄
  • Collections.stream() 을 제공, stream() 메서드는 List 인터페이스에서 제공해주는 메서드
  • filter, map, forEach 같은 고차함수(함수를 인자로 받는 함수)가 제공됨
  • 스트림을 사용하면 연속된 데이터에 대해서 풍부한 고차함수들을 사용하여 강력한 기능을 간결하게 표현 가능
InputStream in = System.in;
OutputStream out = System.out;
//키보드 입출력도 연속된 데이터의 흐름이다
  • stream() 메서드를 수행하면서 위의 Collection, Iterator와 달라진 점은
    1. 이전 방식에서는 .map() .filter() .forEach 각 단계를 수행하면서 Collection 덩어리 전체를 연산하고 다음 단계로 데이터를 넘겼다면
    2. stream을 사용한 방식에서는 데이터 하나가 모든 단계를 거친 후 다음 데이터, 다음데이터 .. 이러한 방식이다.

 

    IntStream s1= Arrays.stream(new int[]{1,2,3});
    Stream<Integer> s = Arrays.asList(1,2,3).stream();
    //int형은 primitive 변수이기 때문에 제네릭에 사용할 수 없으므로 Stream<Integer> 이러한 변수로 사용할 수 없음
    //IntStream : int 배열 객체를 위한 타입


    Stream<Integer> s2= Arrays.stream(new int[]{1,2,3}).mapToObj(i -> Integer.valueOf(i));
    stream<Integer> s3 = Arrays.stream(new int[]{1,2,3}).boxed();
    //이런식으로 primitive 변수의 배열을 boxing 하여 Stream<Integer> 배열로 바꿀 수 있다.

 
    Arrays.stream(new int[]{1,2,3}).boxed().collect(Collectors.toList());
    /*
    --> toList할 때는 collect()라는 기능을 사용. 이렇게 하면 List<Integer> 타입으로 결과가 나오게 됨
    1. boxed()로 변수의 타입을 int -> Integer, 즉 primitive -> wrapper 타입으로 boxing 시킴
    2. collect함수에서 Collectors.toList()로 다시 변화시켰기 때문에 List형으로 바뀜
    */

    Arrays.stream(new int[]{1,2,3}).boxed().toArray(Integer[]::new); //integer[] 타입
    Arrays.stream(new int[]{1,2,3}).boxed().toArray(); //Object[] 타입

 

 

  • Stream 생성 : 2가지 방법이 있음
    • Stream.generate();
    • Stream.iterate();

 

1. Stream.generate()

  • stream은 new 해서 만들수 없다.
    Stream.generate()는 input값으로 Supplier가 들어간다.(input값은 없고 결과값만 있는 거)
  • Stream.generate()의 매개변수로 입력한 데이터를 연속해서 출력한다.
  • straem은 연속된 데이터가 소진될 때 까지 실행되는데 generate하면서 1을 계속 발생시킨 것
//무한 "1" 출력 . . .
Stream.generate(() -> 1).forEach(System.out::println);

//무한 랜덤값 출력
Random r = new Random();
Stream.generate(() -> r.nextInt()).forEach(System.out::println);

//랜덤값 10개 출력
Random r2 = new Random();
Stream.generate(() -> r2.nextInt()).limit(10).forEach(System.out::println);

 

2. Stream.iterate()

  • Stream.iterate()는 매개변수 2개가 필요하다.
  • Stream.iterate(0,(i) -> i + 2)
    • seed : 0 //초기값
    • function : UnaryOperator extends Function<T, T> //입출력값을 가지는 함수형 인터페이스인 Function을 상속
Stream.iterate(0,(i) -> i + 1).forEach(System.out::println); //1,2,3,4... 무한으로 숫자가 올라가면서 출력됨

 

Stream을 생성하는 두 메서드의 차이점

  • generate() : 초기값이 없다.     --> 함수로 Supplier가 사용됨
  • iterate() : 초기값(seed)가 있다. --> 함수로 Function<T,R>이 사용됨

 

Collection ~ Stream 까지의 내용 정리

여러개의 데이터의 묶음을 Collection이라고 함.
데이터 묶음을 하나하나 처리하고 싶을 때 Iterator 방식을 사용한다.
하지만 iterator는 Collection처럼 고차함수를 사용할 수 없다.
이를 해결하는 방법으로 Stream을 사용한다.
stream() 메서드는 List 인터페이스에서 제공해주는 메서드이기 때문에
Collection의 구상체인 List는 Collection 처럼 고차함수를 사용할 수 있게 해준다.


Optional

  • NPE : Null Pointer Exception - 가장 많이 발생하는 에러중의 하나
  • 자바에서는 (거의) 모든것이 레퍼런스 ==> (거의) 모든것이 null이 될 수 있다.
  • null을 사용하지 않고 프로그래밍 하는 방향으로 해야 함

 

null을 사용하지 않는 방법!

(1) EMPTY 객체를 사용하는 방법

User user = new User(22,"강희정");
//이러한 형식의 객체가 있을 때
User user = null; //이런식으로 값으로 null이 들어갈 수도 있지만 사용하지 않는 방향으로 해야됨--> NPE 발생하니까 안됨

User user = new User(0,"");
//이런식으로 프로그램이 이해하지 못하게 임의로 null처럼 지정하는 방식도 나중에 문제가 발생할 수 있다. 때문에 EMPTY 객체를 사용해야됨

// ... User 객체 선언부
public static final User EMPTY = new User(0, "");
//이런식으로 EMPTY를 상수로 선언할 경우에는 임의로 null을 지정할 필요 없이 깔끔하게 코딩 가능
// .getUser()이런 함수로 (user.getUser() == null) 이러한 비교식 대신 (user == User.Empty) 이렇게 깔끔하게 비교 가능하다.
//User 내부에서도 (this == EMPTY) 이렇게 활용 가능

 

(2) Optional을 사용한다.

  • null이 될수도 있는, 안될수도 있는 값들에 대해서 mapping해주는 것
Optional<NewObject> optionalObject = Optional.empty(); //null일때
optionalObject = Optional.of(new NewObject(1, "2")); //값을 넣을 때
  • Optional은 NewObject라는 데이터를 wrapping해서 운반해주는 운반체(값이 있을수도 있고 없을수도 있음). null이 될 수 있는 값들을 운반해주는 운반체
  • 그렇기 때문에 이 변수를 사용하게 되었을때 NewObject가 null이라면 진짜로 null이 아니라 비어있는 Optional을 반환하게 된다.
더보기

Optional 메서드


null 데이터 : Optional.empty()
데이터 : Optional.of( {DATA} )
확인하는 방법은 : .isEmpty(), .isPresent()
사용할 때 : optionalUser.get()

 

 

  • EMPTY 방법은 EMPTY의 존재를 아는 사람들만 사용하는데,(존재를 확실하게 모름)
  • optional방식은 어떻게 취급해야하는지 명확하게 알 수 있음(타입으로 존재하기 때문에 메서드도 정해져있어 사용하기 수월함)
  • @NonNull을 사용하는 방식도 있지만 표준자바에서 제공해주는 방식은 아님(제공이 되는경우 적극적으로 활용하는 방법도 괜찮음)

'TIL' 카테고리의 다른 글

[TIL] 210809  (0) 2021.08.10
[TIL] 210806  (0) 2021.08.09
[TIL] 210804  (0) 2021.08.05
[TIL] 210803  (0) 2021.08.05
[TIL] 210802  (0) 2021.08.04