티스토리 뷰
아래 글은 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]
'프로그래밍 > Back end' 카테고리의 다른 글
[Back end] Spring MVC 리턴 타입 캐시 (0) | 2019.03.17 |
---|---|
[Back end] Java 윈도우 JAVA_HOME 환경변수 설정 (0) | 2019.03.17 |
[Back end] Spring 프레임워크 간단 정리 (0) | 2019.03.14 |
[Back end] Java 용어 (0) | 2019.03.03 |
[Back end] Java 프로그래머가 실수하는 10가지 유형 - 2 (0) | 2019.02.08 |
- Maven
- sort algorithm
- Eclipse
- 리눅스 명령어
- 오라클
- spring
- effective java
- Tomcat
- javascript
- 자바스크립트
- 소프트웨어공학
- 리액트
- 성능분석
- Collection
- Linux 명령어
- React
- 제주도 3박4일 일정
- 회고
- 자바
- 프로그래머스
- 정렬 알고리즘
- 제주도 여행
- 이직
- 경력관리
- 개발환경
- SQL
- Java
- 프로그래머
- 오라클 내장 함수
- 리액트 16
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |