Development/Java

Iterator java.util.NoSuchElementException

Jamie 2022. 3. 13. 21:53
반응형

안녕하세요.

오늘은 Java에서 Iterator 사용시 NoSuchElementException이 발생하는 이유와 이에 대한 해결방법을 설명하도록 하겠습니다.

 

저의 경우는 Iterator를 사용할때 사용방법을 정확히 숙지하지 못하고 사용해서 발생한 에러 메시지입니다.

 

Iterator는 Set, List, Map등 어떤 데이터들의 집합체(Collection)들로부터 정보를 얻어낼 수 있는 기능을 수행할 수 있습니다.

보통 이러한 자료구조들로부터 정보를 얻어낼때 for, while과 같은 반복문과 조건문들을 사용해서 특정 항목의 정보를 얻어내는데,

 

Iterator를 사용하면 동일한 방식으로 접근이 가능하며, 그 안에 있는 특정 항목에 접근할 수 있는 방법을 손쉽게 제공합니다.

 

Iterator에서 자주사용하는 메서드들은 다음과 같습니다. 

hasNext() : 집합체에서 추가로 읽을 수 있는 요소가 있는지 확인할 수 있는 메서드입니다.

next() : 집합체의 다음 데이터를 반환합니다.

remove() : next()로 읽어온 항목을 제거합니다.

 

현재 파라미터로 얻어온 List를 클래스안의 멤버 List에 업데이트하는 메서드를 구현했습니다.

다음과 같이 구성했더니 NoSuchElementException이 발생했습니다.

 

public void update(Info info) {
    ListIterator<Info> iterator = mInfo.listIterator();
    while (iterator.hasNext()) {
        if (iterator.next().getName().equals(info.getName())) {
            iterator.next().setId(info.getId());
            iterator.next().setData(info.getData());
        }
    }
}

다음과 같은 에러메시지가 발생합니다.

Exception in thread "main" java.util.NoSuchElementException
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1000)
	at Iterator.update(Iterator.java:30)
	at Iterator.main(Iterator.java:15)

 

위에 설명드렸듯이, next()는 집합체의 다음 데이터를 반환하는 메서드입니다. 실제 mInfo의 데이터는 2개만 들어있고, update 메서드를 수행하면, iterator.next()가 두번호출되며, iterator가 3번째 데이터를 반환하려고 했으니 NoSuchElementException이 발생하게 됩니다.

 

다음과 같이 고치니 정상적으로 작동합니다.

public void update_ok(Info info) {
    ListIterator<Info> iterator = mInfo.listIterator();
    Info i = iterator.next();
    while (iterator.hasNext()) {
        if (i.getName().equals(info.getName())) {
            i.setId(info.getId());
            i.setData(info.getData());
            break;
        }
    }
}

 

테스트한 전체코드는 아래와 같습니다.

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class IteratorTestClass {

    private List<Info> mInfo;

    public static void main(String[] args) {
        IteratorTestClass itor = new IteratorTestClass();
        Info info = new Info("James", "j1234", "AD920123E0DC0FFF012371293");
        itor.update(info);
        //itor.update_ok(info);
    }

    public IteratorTestClass() {
        mInfo = new ArrayList();
        mInfo.add(new Info("James"));
        mInfo.add(new Info("Relee"));
    }

    public void update(Info info) {
        ListIterator<Info> iterator = mInfo.listIterator();
        while (iterator.hasNext()) {
        if (iterator.next().getName().equals(info.getName())) {
            iterator.next().setId(info.getId());
            iterator.next().setData(info.getData());
        }
    }
}

public void update_ok(Info info) {
    ListIterator<Info> iterator = mInfo.listIterator();
    Info i = iterator.next();
    while (iterator.hasNext()) {
        if (i.getName().equals(info.getName())) {
            i.setId(info.getId());
            i.setData(info.getData());
        }
    }
}
}


class Info {
    private String name;
    private String id;
    private String data;

    public Info(String name) {
        this.name = name;
    }

    public Info(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public Info(String name, String id, String data) {
        this.name = name;
        this.id = id;
        this.data = data;
    }

    public String getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getData() {
        return this.data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

 

참고한 사이트는 다음과 같습니다.

 

감사합니다.

반응형