นากกายเลื่อนลูกปัดสีเดียวกันจากถาดข้อมูลไปยังรางนับเพื่อหาของซ้ำ

Java Collections.frequency: เช็กของซ้ำก่อนรับ batch

พี่โชว์Engineering

batch ขนาดเล็กมักต้องตอบคำถามตรง ๆ ว่า ID นี้ปรากฏกี่ครั้ง Collections.frequency เดิน collection แล้วนับสมาชิกที่เท่ากับเป้าหมายตาม equals ทำให้ validation อ่านตรงความหมายครับ

WHY: เขียน policy ให้เห็นว่า “เกินหนึ่ง” คือปัญหา

เหมือนพนักงานนับคูปองหมายเลขเดียวกันก่อนรับกล่อง ถ้ากฎคือห้าม ID ซ้ำ การเขียน frequency(ids, id) > 1 สื่อ policy ชัดสำหรับรายการสั้นและการตรวจเฉพาะค่า ไม่ต้องสร้าง map นับทุกค่าโดยอัตโนมัติ

import java.util.Collections;
import java.util.List;

public class Main {
    static boolean appearsOnce(List<String> ids, String target) {
        return Collections.frequency(ids, target) == 1;
    }

    public static void main(String[] args) {
        List<String> ids = List.of("job-a", "job-b", "job-a", "job-c");
        assert Collections.frequency(ids, "job-a") == 2;
        assert !appearsOnce(ids, "job-a");
        assert appearsOnce(ids, "job-b");
        assert Collections.frequency(ids, "missing") == 0;
        System.out.println("frequency policy verified");
    }
}

HOW: หนึ่งครั้งคือ O(n), ทุกค่าซ้ำอาจกลายเป็น O(n²)

การเรียกหนึ่ง target เดิน collection หนึ่งรอบ แต่ถ้าวนทุกสมาชิกแล้วเรียก frequency ซ้ำ จะเดินรายการซ้อนกัน สำหรับ batch ใหญ่ให้สร้าง Map<T, Long> ในรอบเดียว หรือใช้ groupingBy(..., counting()) แทน และกำหนดเพดานจำนวนรายการตั้งแต่รับ request

ผลนับขึ้นกับ equals ของสมาชิก หาก object mutable เปลี่ยน field ที่ใช้เทียบระหว่างทาง ผลจะสับสน ควรใช้ value object ที่ immutable และทดสอบ equality contract โดยเฉพาะเมื่อ ID ไม่สนตัวพิมพ์เล็กใหญ่ ให้ normalize ก่อนนับแทนการคาดหวังว่า String.equals จะช่วย

Recap

  • ใช้ frequency สำหรับรายการเล็กหรือ target ไม่กี่ตัว
  • หลีกเลี่ยงเรียกซ้อนทุกสมาชิกใน batch ใหญ่
  • เข้าใจว่า equality มาจาก equals
  • normalize ค่าตามกฎโดเมนก่อนนับ
  • จำกัดขนาด batch ก่อน validation