如何以相同的方式随机化两个ArrayList?


257

我有两个arraylist filelist并且imgList彼此相关,例如,与“ e1.jpg”相关的“ H1.txt”。如何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"};

Answers:


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那个和洗牌了。

这也改善了封装,为您提供了一个属性,使您始终拥有与图像自动相同数量的文件。

如果您真的不喜欢该主意,则可以选择自己编写洗牌代码(Java中有很多经过修改的Fisher-Yates洗牌示例,包括我怀疑的Stack Overflow上的几个示例),并且只在这两个列表上进行操作同时。但是,我强烈建议您使用“改善封装”方法。


11

您可以使用地图执行此操作:

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

这将以随机顺序遍历图像。


5

可以使用shuffle方法完成此操作:

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

而不是拥有两个字符串数组,而是拥有一个包含两个字符串的自定义类的数组。


3

您可以创建一个包含数字0到5的数组,并对其进行随机排列。然后将结果用作“ oldIndex->​​ newIndex”的映射,并将此映射应用于两个原始数组。


2

不能完全确定“自动”是什么意思-您可以创建一个包含两个对象的容器对象:

公共类FileImageHolder {字符串fileName; 字符串imageName; // TODO:在此处插入内容}

然后将其放在数组列表中并对该数组列表进行随机化。

否则,您将需要跟踪每个元素在一个列表中的移动位置,并在另一个列表中将其移动。


2

除非有一种方法可以在元素被改组后检索旧索引,否则我将采用以下两种方法之一进行操作:

A)制作另一个列表multi_shuffler = [0,1,2,...,file.size()]并对其进行随机播放。将其循环以获取随机播放的文件/图像列表的顺序。

ArrayList newFileList = new ArrayList(); ArrayList newImgList = new ArrayList(); 对于(i = 0; i

或B)创建一个StringWrapper类来保存文件/图像名称,并将您已经拥有的两个列表合并为一个:ArrayList CombinedList;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.