import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class SalinanSaatTulis {
    public static void main(String[] args) throws InterruptedException {
        // Bagian 1: CopyOnWriteArrayList -- iterator bekerja pada salinan
        // array yang dibekukan SAAT iterator itu dibuat.
        CopyOnWriteArrayList<String> namaTim =
                new CopyOnWriteArrayList<>(List.of("Budi", "Siti", "Dewi"));
        Iterator<String> pembaca = namaTim.iterator(); // salinan beku: 3 nama

        // Penulisan terjadi SETELAH iterator dibuat -- penulis menambah
        // anggota baru sementara iterator akan dibaca setelahnya.
        Thread penulis = new Thread(() -> namaTim.add("Rina"), "penulis");
        penulis.start();
        penulis.join();

        List<String> yangTerlihat = new ArrayList<>();
        pembaca.forEachRemaining(yangTerlihat::add); // iterasi salinan lama
        System.out.println("yang dilihat iterator : " + yangTerlihat);
        System.out.println("isi terkini           : " + namaTim);

        // Bagian 2: ArrayList biasa dengan pola yang sama -- iterator
        // fail-fast mendeteksi modifikasi struktural dan melempar CME.
        List<String> daftarBiasa = new ArrayList<>(List.of("Budi", "Siti", "Dewi"));
        Iterator<String> pembacaBiasa = daftarBiasa.iterator();
        daftarBiasa.add("Rina"); // modifikasi struktural setelah iterator dibuat
        try {
            while (pembacaBiasa.hasNext()) {
                pembacaBiasa.next();
            }
            System.out.println("iterasi ArrayList biasa selesai tanpa galat");
        } catch (java.util.ConcurrentModificationException e) {
            System.out.println("ArrayList biasa melempar ConcurrentModificationException");
        }
    }
}
