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

Posted

技术标签:

【中文标题】如何以相同的方式随机化两个 ArrayList?【英文标题】:How to randomize two ArrayLists in the same fashion? 【发布时间】:2011-05-12 20:29:40 【问题描述】:

我有两个相互关联的数组列表filelistimgList,例如与“e1.jpg”相关的“H1.txt”。如何根据fileList的随机化自动随机化imgList的列表?就像在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";

【问题讨论】:

【参考方案1】:

使用Collections.shuffle() 两次,两个Random 对象使用相同的种子初始化:

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

使用具有相同种子的两个 Random 对象可确保两个列表将以完全相同的方式进行混洗。这允许两个单独的集合。

【讨论】:

【参考方案2】:

将它们包装在另一个类中,这样您就可以得到一个数组或这些对象的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);

【讨论】:

这是 Java 面向对象的解决方案。也许,应该怎么做... :)【参考方案3】:

最简单的方法是将这两个值封装在一起,形成一个同时具有图像和文件的类型。然后构建一个那个ArrayList并随机播放它。

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

如果您真的不喜欢这个想法,另一种选择是自己编写 shuffle 代码(有很多用 Java 修改的 Fisher-Yates shuffle 示例,包括 Stack Overflow I 上的几个怀疑)并且同时对两个列表进行操作。但我强烈建议采用“改进封装”的方法。

【讨论】:

【参考方案4】:

你可以用地图做到这一点:

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;

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

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

公共类 FileImageHolder 字符串文件名; 字符串图像名; //TODO: 在此处插入内容

然后将其放入数组列表中并随机化该数组列表。

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

【讨论】:

【参考方案9】:

除非有办法在元素被洗牌后检索它们的旧索引,否则我会采用以下两种方法之一:

一) 制作另一个列表 multi_shuffler = [0, 1, 2, ... , file.size()] 并对其进行洗牌。循环遍历它以获取打乱后的文件/图像列表的顺序。

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

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

【讨论】:

以上是关于如何以相同的方式随机化两个 ArrayList?的主要内容,如果未能解决你的问题,请参考以下文章

我需要以相同的随机方式随机打乱两个熊猫数据帧的行

如何使用相同的随机排序对两个数组进行排序

随机化 DataFrame 列中的值

如何使用 group by 子句选择随机行?

如何获得 Firebase 节点的随机子节点?

如何生成两个遵循相似(但不相等)正弦形式的随机数序列?