แม้ว่าจะเป็นกระทู้เก่า แต่การเพิ่มตัวเลือกอื่นอาจไม่เป็นอันตราย (ฟังก์ชั่นแลมบ์ดา JDK 1.8 ดูเหมือนจะทำให้ง่าย);
ปัญหาอาจแบ่งออกเป็นขั้นตอนต่อไปนี้
- รับค่าต่ำสุดสำหรับรายการจำนวนเต็มที่ระบุ (สำหรับสร้างตัวเลขสุ่มที่ไม่ซ้ำกัน)
- รับค่าสูงสุดสำหรับรายการจำนวนเต็มที่ระบุ
- ใช้คลาส ThreadLocalRandom (จาก JDK 1.8) เพื่อสร้างค่าจำนวนเต็มแบบสุ่มเทียบกับค่าจำนวนเต็มต่ำสุดและสูงสุดที่พบก่อนหน้านี้จากนั้นกรองเพื่อให้แน่ใจว่าค่านั้นมีอยู่ในรายการเดิม สุดท้ายใช้ความแตกต่างกับ intstream เพื่อให้แน่ใจว่าตัวเลขที่สร้างขึ้นไม่ซ้ำกัน
นี่คือฟังก์ชั่นพร้อมคำอธิบาย:
private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) {
List<Integer> generatedUniqueIds = new ArrayList<>();
Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new);
Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new);
ThreadLocalRandom.current().ints(minId,maxId)
.filter(e->idList.contains(e))
.distinct()
.limit(numberToGenerate)
.forEach(generatedUniqueIds:: add);
return generatedUniqueIds;
}
ดังนั้นเพื่อให้ได้ตัวเลขสุ่มที่ไม่ซ้ำกัน 11 หมายเลขสำหรับวัตถุรายการ 'allIntegers' เราจะเรียกฟังก์ชันเช่น;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
ฟังก์ชันจะประกาศ arrayList ใหม่ 'createdUniqueIds' และเติมข้อมูลด้วยจำนวนเต็มสุ่มที่ไม่ซ้ำกันจนถึงจำนวนที่ต้องการก่อนส่งคืน
คลาส PS ThreadLocalRandom หลีกเลี่ยงค่า seed ทั่วไปในกรณีที่มีเธรดพร้อมกัน
1..100
(มีอัลกอริทึมที่มีชื่อเสียงสำหรับสิ่งนั้น) แต่หยุดหลังจากที่คุณกำหนดn
องค์ประกอบแรกแล้ว