已知咱们有两个列表java
public class RandomizeTwoList { public static String [] file = {"H1.txt","H2.txt","H3.txt","M4.txt","M5.txt","M6.txt"}; public static ArrayList<String> fileList = new ArrayList<String>(Arrays.asList(file)); public static String [] img = {"e1.jpg","e2.jpg","e3.jpg","e4.jpg","e5.jpg","e6.jpg"}; public static ArrayList<String> imgList = new ArrayList<String>(Arrays.asList(img)); }
其中fileList和imgList中的元素是一一对应的。git
如今咱们但愿对两个列表进行随机排序,要求排序后它们依旧是一一对应的。github
提示: java.util.Collections
可使得一个列表乱序,可是下面的写法是不能够的:数组
import java.util.Collections; public class RandomizeTwoListTest { @Test public void wrongRandomize(){ Collections.shuffle(fileList); Collections.shuffle(imgList); System.out.println(fileList); System.out.println(imgList); // [H3.txt, M5.txt, H2.txt, H1.txt, M6.txt, M4.txt] // [e6.jpg, e3.jpg, e4.jpg, e1.jpg, e2.jpg, e5.jpg] } }
咱们能够看到java.util.Collections
确实可使得一个列表乱序,可是上面两次乱序后列表之间失去了一一对应的关系,因此是不行的。less
那咱们怎么解决呢?dom
咱们以前的演示用例失败的缘由是两次随机化的规则不同,致使结果不能一一对应,那么咱们如今能够code
让它们一一绑定起来,构造出一个list(固然也能够是map、onject)容纳它们,而后再随机排序。排序
@Test public void randomTogether(){ List<List<String>> compoundList = new ArrayList(); for (int i = 0; i < fileList.size(); i++) { List<String> listItem = new ArrayList(); listItem.add(fileList.get(i)); listItem.add(imgList.get(i)); compoundList.add(listItem); } System.out.println(compoundList); // [[H1.txt, e1.jpg], [H2.txt, e2.jpg], [H3.txt, e3.jpg], [M4.txt, e4.jpg], [M5.txt, e5.jpg], [M6.txt, e6.jpg]] Collections.shuffle(compoundList); System.out.println(compoundList); // [[M5.txt, e5.jpg], [H2.txt, e2.jpg], [M4.txt, e4.jpg], [H3.txt, e3.jpg], [H1.txt, e1.jpg], [M6.txt, e6.jpg]] for (int i = 0; i < fileList.size(); i++) { fileList.set(i, compoundList.get(i).get(0)); imgList.set(i, compoundList.get(i).get(1)); } System.out.println(fileList); // [M5.txt, H2.txt, M4.txt, H3.txt, H1.txt, M6.txt] System.out.println(imgList); // [e5.jpg, e2.jpg, e4.jpg, e3.jpg, e1.jpg, e6.jpg] }
参考这样的代码。看起来很复杂,其实思路很简单。get
咱们来讲一下Collections.shuffle 的原理。it
当咱们调用Collections.shuffle(List list)的时候,它其实作了这件事
public static void shuffle(List<?> list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); // harmless race. shuffle(list, rnd); }
那么void shuffle(List<?> list, Random rnd)
又作了什么呢?
简单的来讲,它就是对传进来的list作一次i递减的for循环,而后在每次循环的时候把第i个元素和rnd.nextInt(i)的值互换,这样咱们最终的list就是随机乱序的了。
这里你们明白了吧,若是每次产生的随机值一致,那么它们就随机排序的结果就是一致的。
好了,有的同窗就开始写代码了,写出这样的代码了
@Test public void randomize(){ long seed = System.nanoTime(); Random random = new Random(seed); Collections.shuffle(fileList, random); Collections.shuffle(imgList, random); System.out.println(fileList); System.out.println(imgList); }
注意这样是不行的哦,由于虽然是同一个Random,可是每次调用nextInt的结果是不同的。
应该这样写:
@Test public void randomize2(){ long seed = System.nanoTime(); Collections.shuffle(fileList, new Random(seed)); Collections.shuffle(imgList, new Random(seed)); System.out.println(fileList); System.out.println(imgList); // [M5.txt, M4.txt, H1.txt, H2.txt, H3.txt, M6.txt] // [e5.jpg, e4.jpg, e1.jpg, e2.jpg, e3.jpg, e6.jpg] }
两个Random的随机种子同样,那么他们第i次的nextInt的值也是相等的。