Làm thế nào để chọn ngẫu nhiên hai ArrayLists theo cùng một cách?


257

Tôi có hai danh sách mảng filelistimgListliên quan đến nhau, ví dụ "H1.txt" liên quan đến "e1.jpg". Làm thế nào để tự động ngẫu nhiên danh sách imgListtheo ngẫu nhiên fileList? Giống như trong excel, nếu chúng ta sắp xếp cột nhất định, cột kia sẽ tự động theo?

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);

đầu ra sau khi ngẫu nhiên, ví dụ:

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

đầu ra dự định:

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

Câu trả lời:


585

Sử dụng Collections.shuffle()hai lần, với hai Randomđối tượng được khởi tạo với cùng một hạt giống:

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

Sử dụng hai Randomđối tượng có cùng một hạt giống đảm bảo rằng cả hai danh sách sẽ được xáo trộn theo cùng một cách chính xác. Điều này cho phép hai bộ sưu tập riêng biệt.


121

Gói chúng trong một lớp khác để bạn có thể kết thúc với một mảng hoặc Listcác đối tượng đó.

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

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

Ví dụ sử dụng:

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
Đây là Java, giải pháp hướng đối tượng. Có lẽ, làm thế nào nó nên được thực hiện ... :)
Evan

22

Cách tiếp cận đơn giản nhất là gói hai giá trị lại với nhau thành một loại có cả hình ảnh và tệp. Sau đó xây dựng một ArrayListtrong đó và xáo trộn nó.

Điều đó cũng cải thiện việc đóng gói, cung cấp cho bạn thuộc tính mà bạn sẽ luôn có cùng số lượng tệp như hình ảnh.

Một cách khác nếu bạn thực sự không thích ý tưởng đó là tự mình viết mã xáo trộn (có rất nhiều ví dụ về việc xáo trộn Fisher-Yates đã sửa đổi trong Java, bao gồm một số trên Stack Overflow tôi nghi ngờ) và chỉ hoạt động trên cả hai danh sách tại cùng lúc. Nhưng tôi thực sự khuyên bạn nên đi theo phương pháp "cải thiện đóng gói".


11

Bạn có thể làm điều này với bản đồ:

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

Điều này sẽ lặp qua các hình ảnh theo thứ tự ngẫu nhiên.


5

Điều này có thể được thực hiện bằng phương pháp xáo trộn:

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

Thay vì có hai mảng Chuỗi, hãy có một mảng của một lớp tùy chỉnh chứa hai chuỗi của bạn.


3

Bạn có thể tạo một mảng chứa các số từ 0 đến 5 và xáo trộn các số đó. Sau đó, sử dụng kết quả dưới dạng ánh xạ của "old Index -> new Index" và áp dụng ánh xạ này cho cả mảng ban đầu của bạn.


2

Không hoàn toàn chắc chắn ý của bạn là "tự động" - bạn có thể tạo một đối tượng chứa cả hai đối tượng:

lớp công khai FileImageHolder {String fileName; Chuỗi imageName; // TODO: chèn công cụ vào đây}

Và sau đó đặt nó trong một danh sách mảng và chọn ngẫu nhiên danh sách mảng đó.

Mặt khác, bạn sẽ cần theo dõi từng phần tử di chuyển trong một danh sách và di chuyển nó trong phần còn lại.


2

Trừ khi có cách lấy lại chỉ mục cũ của các yếu tố sau khi chúng bị xáo trộn, tôi sẽ thực hiện theo một trong hai cách:

A) Tạo một danh sách khác multi_shuffler = [0, 1, 2, ..., file.size ()] và xáo trộn nó. Lặp lại nó để có được thứ tự cho danh sách tập tin / hình ảnh được xáo trộn của bạn.

ArrayList newFileList = new ArrayList (); ArrayList newImgList = new ArrayList (); cho (i = 0; i

hoặc B) Tạo một lớp StringWrapper để giữ tên tệp / hình ảnh và kết hợp hai danh sách bạn đã có trong một: ArrayList kết hợp ListList;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.