如何對兩個列表進行亂序處理,同時保持它們的一一對應的關係?

如何對兩個列表進行亂序處理,同時保持它們的一一對應的關係?

已知咱們有兩個列表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

  • 先把fileList第i個元素的值和imgList第i個元素的值綁定起來,構造出新的數組
  • 而後對着數組進行亂序,亂序完成後原理的兩個list的對應依舊保持一致
  • 將list整理還原

方案2: 採起一樣的方式隨機化

咱們來講一下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的值也是相等的。

https://github.com/fish-bugs/...

相關文章
相關標籤/搜索