티스토리 뷰

 

 

아래 글은 Top 10 Mistakes Java Developers Make 번역본이며 일부 첨언을 하였다.

 

1. Convert Array to ArrayList


개발을 하다 보면 배열을 ArrayList로 변환이 필요할 때가 있다.

대부분의 개발자분들이 아주 자연스럽게 아래와 같이 사용을 한다.

java.util에는 Arrays 클래스가 존재하며 Array.asList는 배열을 리스트로 반환해 주기 때문이다.

 

List<String> list = Arrays.asList(arr);

 

 

Arrays.asList

 

이 메소드는 손 쉽게 배열을 컬렉션 관련 유틸을 사용해 캐스팅하여 사용할수는 있지만 제약사항이 있다.

Java API 문서를 참조하면 다음과 같은 설명이 있다.

  • Returns a fixed-size list backed by the specified array. 
  • fixed-size list(고정된 크기)를 반환하기 때문에 element를 추가, 삭제가 불가능하다.

 

ArrayList<String> arrayList = new ArrayList<String>(Array.asList(arr));

 

 

위와 같이 사용을 하면 element 추가, 삭제가 가능하다.

ArrayList 의 생성자는 java.util.Arrays.ArrayList의 상위(Super) 클래스인 Collection type도 받아들일 수 있다.

 

2. Check If an Array Contains a Value


자주 보는 것은 아니지만 가끔 아래와 같이 사용하는 것을 목격하였다.

 

Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);

 

 

위와 같은 사용방법은 동작은 하지만 list를 set으로 변환하는 것은 시간이 소요될 뿐만 아니라 결과적으로도 할 필요가 없다.

아래와 같은 코드로 특정 값이 들어있는지 확인하자.

 

Arrays.asList(arr).contains(targetValue);

 

 

3. Remove an Element from a List Inside a Loop


어떤 개발자가 리스트의 모든 element를 제거하기 위해 아래와 같은 코드를 작성하였다고 생각해보자.

 

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (int i=0; i<list.size(); i++) {     list.remove(i); } System.out.println(list); // output // [b, d]

 

 

output을 보고 이상하다고 생각하시는분들도 있을거라고 생각한다.

위와 같은 코드는 심각한 문제가 될수 있는 실수이다. 개발할때 생각한 값과 다르게 이가 빠진거 처럼 데이터가 나오는 경우에 대부분 이런 경우에 해당된다.

반복문 중 element가 제거되었을때 리스트의 사이즈는 줄어들것이고 각각의 element들의 index 가 변경되므로 위와 같은 결과가 나타난다.

아래와 같은 코드 역시 언뜻 보면 문제가 없어 보일 수 있다.

하지만 ConcurrentModificationException이 발생 된다.

 

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) {     if (s.equals("a"))         list.remove(s); }

 

 

 



 

아래코드는 정상 작동한다.

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); Iterator<String> iter = list.iterator(); while (iter.hasNext()) {     String s = iter.next();     if (s.equals("a"))         iter.remove(); }

 

 

 

 

Iterator 인터페이스는 remve 메소드를 제공하고 있다. 자바(Java) 공식 문서를 보면 이 메소드를 사용하는 것이 컬렉션을 순회하면서 element를 삭제할 수 있는 유일하게 안전한 방법이라고 가이드 하고 있다.

 

Iterator

 

Note that Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

 

또 다른 해결 방법으로는 ArrayList 대신 CopyOnWriteArrayList를 사용하여 문제를 해결할 수 있다.

 

CopyOnWriteArrayList

CopyOnWriteArrayList는 딱 한가지 특징만을 제외하면 ArrayList와 동일하다. CopyOnWriteArrayList를 사용하여 어딘가에 전달될때 복사하여 전달된다.

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) {     if (s.equals("a"))         list.remove(s); } // output // [b, c, d]

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/11   »
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
글 보관함