GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Exception Handling Tránh lỗi ConcurrentModificationException trong Java như thế nào?

Tránh lỗi ConcurrentModificationException trong Java như thế nào?

Đăng vào 27/08/2018 . Được đăng bởi GP Coder . 23047 Lượt xem . Toàn màn hình

Một trong những vấn đề phổ biến trong khi loại bỏ các phần tử từ một ArrayList trong Java là ConcurrentModificationException.

Nếu bạn sử dụng vòng lặp foreach và cố gắng thêm/ xóa phần tử khỏi ArrayList bằng phương thức remove(), bạn sẽ nhận được ConcurrentModificationException.

Tuy nhiên, nếu bạn sử dụng phương thức xóa của Iterator hoặc ListIterator bằng phương thức remove(), bạn sẽ không gặp lỗi này và có thể xóa phần tử đó.

Trong bài viết này, tôi sẽ giải thích, đưa ra một vài ví dụ cho bạn thấy được trường hợp xảy ra lỗi ConcurrentModificationException và cách có thể tránh lỗi này trong khi sửa đổi một ArrayList trong Java.

Nội dung

  • 1 Ví dụ xảy ra lỗi ConcurrentModificationException
  • 2 Tránh lỗi ConcurrentModificationException

Ví dụ xảy ra lỗi ConcurrentModificationException

Thêm/ xóa phần tử khi sử dụng ArrayList.remove() khi duyệt qua for-each


package com.gpcoder.collection.list.ConcurrentModificationException;

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

public class ConcurrentModificationException1 {

	public static void main(String[] args) {
		List<String> languages = new ArrayList<>();
		languages.add("Java");
		languages.add("C#");
		languages.add("PHP");
		languages.add("C++");
		languages.add("Ruby");

		// Using forEach loop to iterate and add/ removing element during iteration will
		// throw ConcurrentModificationException in Java
		for (String language : languages) {
			if (language.equals("C#")) {
				languages.remove(language);
			}
		}
	}
}

Output của chương trình:


Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at com.gpcoder.collection.list.ConcurrentModificationException.ConcurrentModificationException1.main(ConcurrentModificationException1.java:18)


Thêm/ xóa phần tử sử dụng ArrayList.remove() khi duyệt qua Iterator


Iterator<String> iterator = languages.iterator();
while (iterator.hasNext()) {
	String language = iterator.next();
	if (language.equals("C#")) {
		languages.remove(language);
	}
}

Output của chương trình:


Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at com.gpcoder.collection.list.ConcurrentModificationException.ConcurrentModificationException2.main(ConcurrentModificationException2.java:19)

Tránh lỗi ConcurrentModificationException

Sử dụng vòng lặp for-index


for (int i = 0; i < languages.size(); i++) {
	String language = languages.get(i);
	if (language.equals("C#")) {
		languages.remove(language);
	}
}

Lưu ý: với cách này các bạn nên cẩn thận khi get phần tử theo index, có thể sẽ gặp lỗi IndexOutOfBoundsException.

Ví dụ:


for (int i = 0; i < languages.size(); i++) {
	String language = languages.get(i);
	if (language.equals("Ruby")) {
		languages.remove(language);
	}
	System.out.println(languages.get(i)); // IndexOutOfBoundsException
}

Output của chương trình:


Java
C#
PHP
C++
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
	at java.util.ArrayList.rangeCheck(ArrayList.java:653)
	at java.util.ArrayList.get(ArrayList.java:429)
	at com.gpcoder.collection.list.ConcurrentModificationException.ForIndexExample.main(ForIndexExample.java:21)

Sử dụng phương thức remove() được hỗ trợ bởi Iterator


Iterator<String> iterator = languages.iterator();
while (iterator.hasNext()) {
	String language = iterator.next();
	if (language.equals("C#")) {
		// languages.remove(language); // Don't use ArrayList.remove()
		iterator.remove();
	}
}

Không remove trong khi duyệt các phần tử

Nếu chúng ta muốn giữ vòng lặp for-each, thì chúng ta cần đợi cho đến khi kết thúc trước khi chúng ta xóa các phần tử.


List<String> toRemove = new ArrayList<>();
for (String language : languages) {
	if (language.equals("C#") || language.equals("Ruby")) {
		toRemove.add(language);
	}
}
languages.removeAll(toRemove); // [Java, PHP, C++]

Sử dụng phương thức removeIf() trong Java 8


languages.removeIf(language -> language.equals("C#") || language.equals("Ruby"));

Sử dụng Stream filter() trong Java 8


List<String> removedList = languages.stream()
	.filter(language -> language.equals("C#") || language.equals("Ruby"))
	.collect(Collectors.toList());

Trong bài viết này, tôi đã trình bày cho bạn thấy một số trường hợp có thể gặp phải nếu bạn thêm/ xóa một phần tử khi đang duyệt và cũng đã cung cấp một số giải pháp để giải quyết lỗi ConcurrentModificationException. Hy vọng bài viết giúp ích cho các bạn, hẹn gặp lại ở các bài viết tiếp theo.

4.9
31
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Basic Java, Exception Handling, Java Core Được gắn thẻ: Collection, Exception, Java 8

Một số nguyên tắc, định luật trong lập trình
Giới thiệu Design Patterns

Có thể bạn muốn xem:

  • Tổng quan về ngôn ngữ lập trình java (18/10/2017)
  • Xử lý ngoại lệ trong Java (Exception Handling) (06/11/2017)
  • Autoboxing và Unboxing trong Java (26/10/2017)
  • Enum trong java (09/11/2017)
  • Mệnh đề if-else trong java (26/10/2017)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (97436 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97121 lượt xem)
  • Giới thiệu Design Patterns (86802 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (85605 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83149 lượt xem)

Nội dung bài viết

  • 1 Ví dụ xảy ra lỗi ConcurrentModificationException
  • 2 Tránh lỗi ConcurrentModificationException

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link