티스토리 뷰

Iterator는 여러 데이터의 묶음을 풀어서 하나씩 처리할 수 있는 수단을 제공한다.

  • iterator.next()를 통해서 다음 데이터를 조회할 수 있다.
  • 다음 데이터를 읽을 수 있지만, 이전 데이터를 읽을 수는 없다.
  • Iterator를 사용하면서 데이터들에 대해 map이나 filter를 적용할 수는 없다.
//Main.java
public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A", "AB", "ABC", "ABCD", "ABCDE");
        Iterator<String> iter = list.iterator();
        
        while (iter.hasNext()) System.out.println(iter.next());
    }
}

Stream은 데이터의 연속이다.

  • 스트림 기능은 Java 8 이상부터 사용 가능하다.
  • 자바에서는 컬렉션 객체들에 대해서 stream()을 사용할 수 있는 방법을 제공한다. (Collections.stream())
  • filter, map, forEach 같은 고차함수(함수를 인자로 받는 함수)를 사용할 수 있다.
  • System.in, System.out은 스트림이다.(OutputStream, InputStream) 하지만 여기서 사용할 Stream은 데이터에 대한 스트림이다.
  • Stream은 데이터를 한 건씩 처리를 한다. 즉 method chaining이 있을 때, 데이터를 하나씩 처리한다. 데이터를 처리할 필요가 없을 때는 이후로 넘어가지 않고, 처리할 필요가 있을 때만 처리를 하는 lazy evaluation이 구현되어 있다.
    • 즉 filter등에 의해 중간에 걸러지면, 해당 데이터는 그 다음 메소드를 진행하지 않는다.
//Main.java
public class Main {
    public static void main(String[] args) {
        Arrays.asList("A", "AB", "ABC", "ABCD", "ABCDE")
            .stream()
            .map(String::length)
            .filter(i -> i % 2 == 1)
            .forEach(System.out::println);
    }
}
  • 배열은 리스트가 아니기 때문에 stream()메서드가 없다. Arrays.stream()을 통해 stream()처럼 사용할 수 있다.
  • 하지만 primitive type을 제네릭으로 사용할 수 없기 때문에 Stream<Type>이 아니라 IntStream 등의 형식으로 사용한다.
  • IntStream 등의 primitive type stream에서 map(i -> Integer.valueOf(i))를 쓰거나, boxed() 메소드를 사용하면 Stream<Type>형식으로 사용할 수 있다.
  • Stream<> 형에서 다시 리스트로 변환할 수 있다. toArray(Type[]::new) 를 사용한다.
//Main.java
public class Main {
    public static void main(String[] args) {
        Stream<Integer> s = Arrays.asList(1,2,3).stream();
        IntStream s2 = Arrays.stream(new int[]{1,2,3});
        Stream<Integer> s3 = s2.map(i -> Integer.valueOf(i));
        Stream<Integer> s4 = s2.boxed();
        List<> list = s.toArray(Integer[]::new);
    }
}
  • Stream을 만들 때는 Stream.generate()와 Stream.iterate()로 만들 수 있다.
//Main.java
public class Main {
    public static void main(String[] args) {
        Random r = new Random();
        // generate로 생성하는 방법
        Stream.generate(r::nextInt) // 난수를 계속해서 생성한다.
            .limit(10); //10개까지만 생성한다.
            .forEach(System.out::println) // 출력한다.
        //-----------------------
        // iterate로 생성하는 방법
        //0에서 시작해서 두 번째 인자에 값을 넣고 생성한다. 다시 그 수가 input이 된다.
        Stream.iterate(0, (i) -> i + 1)
            .limit(10)
            .forEach(System.out::println);
    }
}
//Main.java
public class Main {
    public static void main(String[] args) {
        Random r = new Random();
        int[] arr = Stream.generate(() -> r.nextInt(9) + 1) // 1~9 사이 랜덤한 수 생성
            .distinct() // 중복되는 수가 나오지 않게 함
            .limit(3) // 수 3개 뽑기
            .sorted(Comparator.reverseOrder())// 큰 수 -> 작은 수 로 뽑기
            //.map()은 Object -> Object
            .mapToInt(i -> i) // IntStream으로 생성
            .toArray(); // primitive 타입 배열의 경우 매개변수로 배열 생성자를 넣어줄 필요가 없음
        System.out.println(Arrays.toString(arr)); // 배열안의 데이터 출력 = Arrays.toString()
    }
}

스트림을 사용하면 연속된 데이터들에 대해서 다양한 고차함수들을 사용하여 간결하게 표현할 수 있다.

728x90
반응형
댓글
반응형
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함