ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 Collection Iterator
    자바(Java) 강의 2019. 5. 4. 16:11

    이번 포스트에서는 자바의 Collection을 반복하는 몇가지 방법에 대해 소개하도록 한다. 특히 반복문이 아닌 Collection이 구현하는 Iterator 인터페이스를 이용해 반복하는 방법을 다룬다. 또한 이 포스트에서는 List/Set과 같이 단독 엘리멘트를 저장하는 컬렉션과 Map처럼 Key-Value 페어를 저장하는 컬렉션의 예제를 포함한다.

    목표

    • Iterator

    • while을 이용하는 방법

    • for를 이용하는 방법

    • ***for-each를 이용하는 방법 

    • ***stream for-each를 이용하는 방법 

    ***은 많이 쓰이는 방법을 의미한다. 다 읽을 시간이 없고 당장 써먹고 싶으면 ***만 읽어도 좋다.

    Iterator

    Iterator 인터페이스로 반복을 하기 위해서는 몇 가지 메서드를 알아야 한다. 첫번째는 iterator메서드, 두번째는 hasNext와 next메서드이다.

    iterator() 메서드는 Iterator를 사용하는 모든 Collection이 구현하는 메서드이다. 이 메서드는 Iterator 인터페이스를 리턴한다.

    hasNext() 메서드는 말 그대로, 이 다음번 엘리먼트가 존재하면 true, 존재하지 않으면 false를 리턴한다. 따라서 hasNext를 이용해 언제 반복을 중단해야하는지 알 수 있다. next() 메서드는 해당 반복의 다음 엘리먼트를 리턴한다. 예를 들어 List에 1, 2, 3이 들어있다고 치자. next()를 하면 1을 리턴한다. 그 다음 바로 next()를 또 하면 2를 리턴한다. 

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    public class Main {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);

    Iterator<Integer> it = list.iterator();
    System.out.println(it.next());
    System.out.println(it.next());
    System.out.println(it.next());

    }
    } 1 2 3

    it.next를 할 때마다 한 칸씩 다음 엘리먼트로 넘어간다고 생각하면 쉽다. 이제 각종 반복문을 이용해 반복하는 방법에 대해 알아보자.

    while을 이용하는 방법

    List를 이용한 예제

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    public class Main {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);

    Iterator<Integer> it = list.iterator();
    while(it.hasNext()) {
    Integer element = it.next();
    System.out.println(element);
    }

    }
    }

    위처럼 List 컬렉션에 존재하는 iterator를 불러와 사용할 수 있다.

    Map을 이용한 예제

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    Iterator<Integer> it = map.keySet().iterator();
    while(it.hasNext()) {
    Integer key = it.next();
    String value = map.get(key);
    System.out.println(key + " - " + value);
    }
    } }

    Map은 key, value로 다뤄야 하기 때문에 keySet의 iterator를 가져와 이를 반복한다. Entry를 이용하는 방법도 있다.

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator();
    while(it.hasNext()) {
    Map.Entry<Integer, String> entry = it.next();
    System.out.println(entry.getKey() + " - " + entry.getValue());
    }
    }
    }

    for를 이용하는 방법

    List를 이용한 예제

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);

    for(Iterator<Integer> it = list.iterator(); it.hasNext();) {
    System.out.println(it.next());
    }
    } }

    반복문에 while에서 했던 것과 마찬가지로 조건을 넣어 반복해준다.

    Map을 이용한 예제

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
    Integer key = it.next();
    String value = map.get(key);
    System.out.println(key + " - " + value);
    }
    } }

    Entry를 이용하는 방법은 아래와 같다.

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    for (Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator(); it.hasNext(); ) {
    Map.Entry<Integer, String> entry = it.next();
    System.out.println(entry.getKey() + " - " + entry.getValue());
    }
    }
    }

    ***for-each를 이용하는 방법 

    for-each는 간단해 아주 많이 쓰인다.

    List를 이용하는 방법

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);

    for(Integer element : list) {
    System.out.println(element);
    }
    } }

    element에는 1->2->3이 차례대로 들어갈 것이다. 말그대로 list에 있는 엘리먼트를 하나씩 element라는 변수에 넣고 아래의 코드를 실행하라는 뜻이다. 

    Collection이 구현하는 foreach를 이용 할 수도 있다. (Java 8)

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);

    list.forEach(System.out::println);
    }
    }

    Map을 이용한 예제

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    for (Integer key : map.keySet() ) {
    System.out.println(key + " - " + map.get(key));
    }
    }
    }

    entrySet을 이용하는 방법은 아래와 같다.

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    for (Map.Entry<Integer,String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " - " + entry.getValue());
    }
    }
    }

    마찬가지로 Collection이 구현하는 forEach를 이용하는 방법도 있다. 내 생각엔 가장 간결한 방법인것 같다.

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    map.forEach((key, value) -> System.out.println(key + " - " + value));
    }
    }

    ***stream for-each를 이용하는 방법 

    java 8이후로는 stream을 이용하는 방법도 많이 사용되고 있다. Stream foreach의 경우는 단독으로 사용하는 경우는 별로 없다. 위에서 Collection이 구현하는 forEach를 사용하면 되기 때문이다. 하지만 stream이 제공하는 filter/map같은 다른 메서드를 사용후 forEach를 해야하는 경우 유용하다.

    List를 이용한 예제

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);

    list.stream().forEach(System.out::println);         // 또는 list.stream().forEach(e -> System.out.println(e));
    }
    }

    Map을 이용한 예제

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    map.keySet().stream().forEach(key -> System.out.println( key + " - " + map.get(key)));
    }
    }

    Entry를 이용하는 방법은 다음과 같다.

    import java.util.*;

    public class Main {
    public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");

    map.entrySet().stream()             .forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));
    }
    }

    이번 포스트에서는 자바의 Iterator를 이용해 Collection을 반복하는 방법에 대해 알아보았다. 새로 배운게 있거나 유용한 정보라고 생각하면 하트를 눌르자.


     


    댓글

f.software engineer @ All Right Reserved