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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4228975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:48:27  来源:igfitidea点击:

How to randomize two ArrayLists in the same fashion?

javalistcollectionsarraylist

提问by Jessy

I have two arraylist filelistand imgListwhich related to each other, e.g. "H1.txt" related to "e1.jpg". How to automatically randomized the list of imgListaccording to the randomization of fileList? Like in excel, if we sort certain column, the other column will automatically follow?

我有两个数组列表filelistimgList它们相互关联,例如与“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);

output after randomization e.g.:

随机化后的输出,例如:

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

intended output:

预期输出:

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

采纳答案by Michael Borgwardt

Use Collections.shuffle()twice, with two Randomobjects initialized with the same seed:

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

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

Using two Randomobjects with the same seed ensures that both lists will be shuffled in exactly the same way. This allows for two separate collections.

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

回答by BalusC

Wrap them in another class so that you can end up with a single array or Listof those objects.

将它们包装在另一个类中,以便您最终可以得到单个数组或List这些对象。

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

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

Usage example:

用法示例:

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

回答by Jon Skeet

The simplest approach is to encapsulate the two values together into a type which has both the image and the file. Then build an ArrayListof thatand shuffle it.

最简单的方法是将两个值一起封装到一个类型中,该类型同时包含图像和文件。然后建立一个ArrayList那个和洗牌了。

That improves encapsulation as well, giving you the property that you'll always have the same number of files as images automatically.

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

An alternative if you reallydon't like that idea would be to write the shuffle code yourself (there are plenty of examples of a modified Fisher-Yates shufflein Java, including several on Stack Overflow I suspect) and just operate on both lists at the same time. But I'd strongly recommend going with the "improve encapsulation" approach.

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

回答by EboMike

Instead of having two arrays of Strings, have one array of a custom class which contains your two strings.

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

回答by jjnguy

You could do this with maps:

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

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

This will iterate through the images in the random order.

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

回答by Mark Byers

You can create an array containing the numbers 0 to 5 and shuffle those. Then use the result as a mapping of "oldIndex -> newIndex" and apply this mapping to both your original arrays.

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

回答by aperkins

Not totally sure what you mean by "automatically" - you can create a container object that holds both objects:

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

public class FileImageHolder { String fileName; String imageName; //TODO: insert stuff here }

公共类 FileImageHolder { 字符串文件名;字符串图像名称;//TODO: 在这里插入东西 }

And then put that in an array list and randomize that array list.

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

Otherwise, you would need to keep track of where each element moved in one list, and move it in the other one as well.

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

回答by ajwood

Unless there's a way to retrieve the old index of the elements after they've been shuffled, I'd do it one of two ways:

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

A) Make another list multi_shuffler = [0, 1, 2, ... , file.size()] and shuffle it. Loop over it to get the order for your shuffled file/image lists.

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

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

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

or B) Make a StringWrapper class to hold the file/image names and combine the two lists you've already got into one: ArrayList combinedList;

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

回答by Rohit Goyal

This can be done using the shuffle method:

这可以使用 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;