일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 데이터베이스
- restTemplate
- @ControllerAdvice
- Item04
- Proxy Patter
- Effetive Java
- springboot
- Spring Boot
- SQL 삽입 공격
- Service Locator
- multi module
- Web
- 디자인 패턴
- NotEmpty
- db
- deleteById
- Effective Java
- @Valid
- Service Locator 패턴
- 플라이웨이트
- @SpyBean
- 트랜잭션
- Firebase
- java
- JPA
- FCM
- 이펙티브 자바
- Connection Pool
- @MockBean
- NotBlank
- Today
- Total
NoTimeForDawdling
[Java] 불변 리스트(Immutable ArrayList) 본문
불변 리스트를 생성하는 방법을 알아보기에 앞서 불변 객체가 주는 장점을 알아보겠습니다.
Immutable Object 장점
- 불변 객체는 생성된 시점의 상태를 파괴될 때까지 간직하고 있으므로 Thread Safe 하여 따로 동기화할 필요가 없습니다.
- 불변 객체는 어떤 스레드도 다른 스레드에게 영향을 줄 수 없으므로 안심하고 공유할 수 있습니다.
- 불변 객체는 그 자체로 *실패 원자성을 제공합니다. 즉, 상태가 절대 변하지 않으므로 잠깐이라도 불일치 상태에 빠질 가능성이 없습니다.
- 실패 원자성: 메서드에서 예외가 발생한 후에도 그 객체는 여전히(메서드 호출 전과 똑같은) 유효한 상태여야 한다.
Immutable ArrayList 만드는 방법
1. Collections.unmodifiableList()
첫 번째 방법으로 Collections.unmodifiableList()를 사용하는 방법이 있습니다.
private void unmodifiableListExam() {
String[] alphabet = {"A", "B", "C"};
List<String> unmodifiableList = Collections.unmodifiableList(Arrays.asList(alphabet));
for (String unmodifiableValue : unmodifiableList) {
System.out.print(unmodifiableValue + " "); // A B C
}
}
다음 테스트 코드를 통해 Collections.unmodifiableList()로 만든 List가 불변인지 확인해 보겠습니다.
public class ImmutableListTest {
@Test(expected = UnsupportedOperationException.class)
public void unmodifiableListTest() {
String[] alphabet = {"A", "B", "C"};
List<String> immutableList = Collections.unmodifiableList(Arrays.asList(alphabet));
immutableList.set(0, "D");
}
}
위와 같이 테스트가 잘 통과된 것을 확인할 수 있습니다.
2. List.of() (Java 9)
두 번째 방법으로 List.of()를 사용하는 방법이 있습니다.
이 방법은 Java 9 버전부터 사용할 수 있습니다.
private void listOfExam() {
String[] alphabet = {"A", "B", "C"};
List<String> immutableList = List.copyOf(Arrays.asList(alphabet));
for (String immutableValue : immutableList) {
System.out.print(immutableValue + " "); // A B C
}
}
다음 테스트 코드를 통해 List.of()로 만든 List가 불변인지 확인해 보겠습니다.
public class ImmutableListTest {
@Test(expected = UnsupportedOperationException.class)
public void ListOfTest() {
String[] alphabet = {"A", "B", "C"};
List<String> immutableList = List.of(alphabet);
immutableList.set(0, "D");
}
}
Collections.unmodifiableList() vs List.of()
Collections.unmodifiableList()를 사용하면 Intellij에서 다음과 같이 List.of()를 사용할 것을 추천합니다.
지금부터 코드를 통해 둘의 차이를 알아보겠습니다.
Collections.unmodifiableList()
private void unmodifiableListTest() {
String[] alphabet = {"A", "B", "C"};
final List<String> unmodifiableList = Collections.unmodifiableList(Arrays.asList(alphabet));
// 원본 데이터 변환
alphabet[0] = "D";
for (String unmodifiableValue : unmodifiableList) {
System.out.print(unmodifiableValue + " "); // D B C
}
}
위 코드는 원본 데이터(String 배열)을 바꿨는데 Collections.unmodifiableList()로 생성한 List의 값도 같이 변경된 것을 알 수 있습니다.
즉, 원본 데이터를 바꿈으로써 완벽한 Immutable을 구현하지 못했다는 것을 알 수 있습니다.
또 하나 알 수 있는 것은 원본 객체의 주소값을 가져오는 것 같습니다.
List.of()
private void listOfTest() {
String[] alphabet = {"A", "B", "C"};
List<String> immutableList = List.copyOf(Arrays.asList(alphabet));
// 원본 데이터 변환
alphabet[0] = "D";
for (String immutableValue : immutableList) {
System.out.print(immutableValue + " "); // A B C
}
}
List.of()로 생성한 List 값은 원본 데이터가 변경되어도 영향을 끼치지 않음을 알 수 있습니다.
이렇게 둘의 차이를 비교해 본다면 Collections.unmodifiableList() 보다 List.of()가 좀 더 안전하다는 것을 알 수 있습니다.
참고
'Java' 카테고리의 다른 글
접근 제어자(Access Modifier) (0) | 2021.02.24 |
---|---|
Enum 클래스 파헤치기 (0) | 2021.02.23 |
Arrays.asList() (0) | 2021.02.15 |
Wrapper class Cache 파헤치기 (0) | 2021.02.13 |
Java Virtual Machine(JVM) (0) | 2021.02.13 |