วิธีการสุ่ม ArrayLists สองแบบในแบบเดียวกันได้อย่างไร


257

ฉันมี arraylist สองรายการfilelistและimgListเกี่ยวข้องกันเช่น "H1.txt" ที่เกี่ยวข้องกับ "e1.jpg" วิธีการสุ่มรายการโดยอัตโนมัติimgListตามการสุ่มของfileList? เช่นเดียวกับใน excel ถ้าเราจัดเรียงคอลัมน์บางคอลัมน์คอลัมน์อื่นจะตามมาโดยอัตโนมัติ

String [] file = {"H1.txt","H2.txt","H3.txt","M4.txt","M5.txt","M6.txt"};
ArrayList<String> fileList = new ArrayList<String>(Arrays.asList(file));

String [] img = {"e1.jpg","e2.jpg","e3.jpg","e4.jpg","e5.jpg","e6.jpg"};
ArrayList<String> imgList = new ArrayList<String>(Arrays.asList(img));

//randomized files
Collections.shuffle(fileList);

ผลลัพธ์หลังจากการสุ่มเช่น:

fileList = {"M4.txt","M6.txt","H3.txt","M5.txt","H2.txt","H1.txt"};

เอาท์พุทตั้งใจ:

 imgList = {"e4.jpg","e6.jpg","e3.jpg","e5.jpg","e2.jpg","e1.jpg"};

คำตอบ:


585

ใช้Collections.shuffle()สองครั้งโดยมีRandomวัตถุสองรายการที่เริ่มต้นด้วยเมล็ดเดียวกัน:

long seed = System.nanoTime();
Collections.shuffle(fileList, new Random(seed));
Collections.shuffle(imgList, new Random(seed));

การใช้Randomวัตถุสองชิ้นที่มีเมล็ดเดียวกันทำให้มั่นใจได้ว่าทั้งสองรายการจะถูกสับในลักษณะเดียวกัน สิ่งนี้อนุญาตให้มีสองคอลเล็กชันแยกกัน


121

ห่อไว้ในคลาสอื่นเพื่อให้คุณสามารถจบด้วยอาร์เรย์เดียวหรือListของวัตถุเหล่านั้น

public class Data {
    private String txtFileName;
    private String imgFileName;

    // Add/generate c'tor, getter/setter, equals, hashCode and other boilerplate.
}

ตัวอย่างการใช้งาน:

List<Data> list = new ArrayList<Data>();
list.add(new Data("H1.txt", "e1.jpg"));
list.add(new Data("H2.txt", "e2.jpg"));
// ...

Collections.shuffle(list);

10
นี่คือ Java, การแก้ปัญหาเชิงวัตถุ บางทีมันควรจะทำยังไงดี ... :)
Evan

22

วิธีที่ง่ายที่สุดคือการรวมสองค่าเข้าด้วยกันเป็นประเภทที่มีทั้งรูปภาพและไฟล์ แล้วสร้างArrayListของที่และสับ

ซึ่งช่วยปรับปรุงการห่อหุ้มด้วยเช่นกันให้คุณสมบัติที่คุณจะมีจำนวนไฟล์เท่ากันกับรูปภาพโดยอัตโนมัติ

ทางเลือกถ้าคุณจริงๆไม่ชอบความคิดที่ว่าจะเขียนรหัสการสับเปลี่ยนตัวเอง (มีความอุดมสมบูรณ์ของตัวอย่างของการแก้ไขสับเปลี่ยน Fisher-Yatesใน Java รวมถึงหลายกองมากเกินฉันต้องสงสัย) และเพียงแค่ทำงานบนทั้งสองรายการที่ ในเวลาเดียวกัน แต่ฉันขอแนะนำอย่างยิ่งให้ใช้วิธี "ปรับปรุงการห่อหุ้ม"


11

คุณสามารถทำได้ด้วยแผนที่:

Map<String, String> fileToImg:
List<String> fileList = new ArrayList(fileToImg.keySet());
Collections.shuffle(fileList);
for(String item: fileList) {
    fileToImf.get(item);
}

การทำเช่นนี้จะวนซ้ำรูปภาพต่าง ๆ ตามลำดับแบบสุ่ม


5

สิ่งนี้สามารถทำได้โดยใช้วิธีการสลับ:

private List<Integer> getJumbledList() {
     List<Integer> myArrayList2 = new ArrayList<Integer>();
        myArrayList2.add(8);
        myArrayList2.add(4);
        myArrayList2.add(9);
        Collections.shuffle(myArrayList2);
        return myArrayList2;

4

แทนที่จะมี Strings สองแถวให้มีหนึ่งอาร์เรย์ของคลาสที่กำหนดเองซึ่งมีสองสตริงของคุณ


3

คุณสามารถสร้างอาร์เรย์ที่มีหมายเลข 0 ถึง 5 และสับเปลี่ยนได้ จากนั้นใช้ผลลัพธ์เป็นแผนที่ของ "oldIndex -> newIndex" และใช้การจับคู่นี้กับทั้งอาร์เรย์ดั้งเดิมของคุณ


2

ไม่แน่ใจว่าสิ่งที่คุณหมายถึงโดย "อัตโนมัติ" - คุณสามารถสร้างวัตถุภาชนะที่มีทั้งวัตถุ:

FileImageHolder ระดับสาธารณะ {String ชื่อไฟล์; String ชื่อภาพ; // TODO: แทรกสิ่งที่นี่}

จากนั้นใส่มันไว้ในรายการอาเรย์แล้วสุ่มรายการอาเรย์นั้น

มิฉะนั้นคุณจะต้องติดตามว่าแต่ละองค์ประกอบย้ายไปอยู่ในรายการใดรายการหนึ่งและย้ายไปที่อีกองค์ประกอบหนึ่งเช่นกัน


2

หากไม่มีวิธีในการเรียกคืนดัชนีเก่าขององค์ประกอบหลังจากที่สับแล้วฉันจะทำหนึ่งในสองวิธี:

A) สร้างรายการอื่น multi_shuffler = [0, 1, 2, ... , file.size ()] และสลับ วนซ้ำเพื่อรับใบสั่งซื้อสำหรับรายการไฟล์ / รูปภาพแบบสับของคุณ

ArrayList newFileList = new ArrayList (); ArrayList newImgList = new ArrayList (); สำหรับ (i = 0; i

หรือ B) สร้างคลาส StringWrapper เพื่อเก็บชื่อไฟล์ / รูปภาพและรวมสองรายการที่คุณมีอยู่แล้ว: ArrayList ที่รวมรายการ;

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.