2023. 3. 7. 11:40ใJAVA/Effective JAVA
item21. ์ธํฐํ์ด์ค๋ ๊ตฌํํ๋ ์ชฝ์ ์๊ฐํด ์ค๊ณํ๋ผ.
" p.137. ConcurrentModificationException"
ConcurrentModificationException
: This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
ํ์ฌ ๋ฐ๋๋ฉด ์๋๋ ๊ฒ์ ์์ ํ ๋ ๋ฐ์ํ๋ ์์ธ
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
-> ๊ทผ๋ฐ ConcurrentModificationException์ ๋ฉํฐ ์ค๋ ๋๊ฐ ์๋ ์ฑ๊ธ ์ค๋ ๋์์๋ ๋ฐ์ํ ์ ์๋ค.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<Integer> numbers2 = new ArrayList<>(); // ๋ณ๊ฒฝ ๊ฐ๋ฅ
numbers2.add(1);
numbers2.add(2);
numbers2.add(3);
numbers2.add(4);
numbers2.add(5);
์ฐ์ List.of ๋ก ๋ง๋ numbers์ ๊ทธ๋ฅ new Arraylist()ํด์ ๋ง๋ numbers2๋ ๊ฐ์๊น?
-> ๋ต์ ์๋๋ค.
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5);
}
์๋ํ๋ฉด List.of ๋ก ๋ง๋ ์ปฌ๋ ์ ์ ImmutableCollection์ผ๋ก ์ด๋ฅผ ์์ ํ๋ ค๊ณ ํ๋ฉด ์๋ฌ๊ฐ ๋๋ค.
for (Integer number : numbers)
{
if (number == 3) {
numbers.remove(number);
}
}
๋ฐ๋ผ์ ์ด๋ ๊ฒ remove๋ฅผ ํ๋ ค๊ณ ํ๋ฉด UnsupportedOperation ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
for (Integer integer : numbers2)
{
if (integer == 3) {
numbers2.remove(integer);
}
}
๊ทผ๋ฐ ์ด์ ์ฌ๊ธฐ์ numbers2์ ๊ฐ์ ์ํํ๋ฉด์ ๊ทธ ์ค 3์ removeํ๋ค๊ณ ํ ๋ ConcurrentModificationException ์ด ๋ฐ์ํ๋ค.
fail-fast iterator๋ฅผ ์ฌ์ฉํด ์ปฌ๋ ์ ์ ์ํํ๋ ์ค์ ์ปฌ๋ ์ ์์ remove ํ๋ฉด ์ฑ๊ธ ์ค๋ ๋ ์ํฉ์์๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
์ด ์๋ฌ๋ฅผ ๋ฐ์ํ์ง ์์ผ๋ฉด์ ์ปฌ๋ ์ ์ ํน์ ๊ฐ์ ์ ๊ฑฐํ๊ณ ์ถ๋ค๋ฉด
๋ฐฉ๋ฒ1) iterator remove ์ฌ์ฉ
for (Iterator<Integer> iterator = numbers2.iterator(); iterator.hasNext();)
{
Integer integer = iterator.next();
if (integer == 3) {
iterator.remove();
}
}
์์์๋ iterator๊ฐ Collection์ ๊ฐ์ด ์ ๊ฑฐ๋์ง ๋ชฐ๋์ง๋ง iterator removeํ๋ฉด iterator๊ฐ ์ง์ ์ ๊ฑฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
๋ฐฉ๋ฒ2) index ์ฌ์ฉํ๊ธฐ
for (int i = 0; i< numbers2.size(); i++)
{
if (numbers2.get(i) == 3) {
numbers2.remove(numbers2.get(i));
}
}
์ด ๋ฐฉ๋ฒ์ ๊ทธ๋ฅ index ๊ฐ์ ์ฌ์ฉํด์ ์ ๊ฑฐํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๋ฐฉ๋ฒ3) removeIf ์ฌ์ฉํ๊ธฐ
numbers2.removeIf(number -> number == 3);
numbers2.forEach(System.out::println);
๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด๋ค. removeIf ์์ filter๋ก ์กฐ๊ฑด์ด true์ด๋ฉด ์ด์ ๊ทธ ๊ฐ์ ์ ๊ฑฐํด์ค๋ค.