How do I unorder two lists while maintaining their one-to-one correspondence?

Keywords: Java github

How do I unorder two lists while maintaining their one-to-one correspondence?

We know we have two lists

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

The elements in the fileList and imgList correspond one to one.

Now we want to sort the two lists randomly, requiring that they remain one-to-one after sorting.

Tip: java.util.Collections can make a list out of order, but the following is not possible:

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]
    }
}

We can see that java.util.Collections can really make a list out of order, but the list loses a one-to-one relationship after the two previous chaos, so it's not possible.

So how can we solve it?

Option 1: Bind them together

The reason why our previous presentation case failed was that the rules of the two randomizations were different, so the results could not be matched, so we can now

Bind them together, construct a list (or map, onject, of course) to hold them, and then sort them randomly.

    @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]
    }

Refer to this code.It looks complicated, but the idea is simple.

  • First bind the value of the fileList element i I to the value of the imgList element i I to construct a new array
  • Then the array is unordered, and the corresponding list s of the two principles remain the same after the unordering is completed
  • Collate and Restore list

Option 2: Randomize in the same way

Let's talk about how Collections.shuffle works.

When we call Collections.shuffle(List list), it actually does this

    public static void shuffle(List<?> list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }

So what did void shuffle (List<?> List, Random rnd) do?

Simply put, it does an i-decreasing for loop on the incoming list, and then exchanges the value of the first element with the value of rnd.nextInt(i) each time, so that our final list is randomly out of order.

Now you can see that if the random values are the same each time they are generated, they will be sorted randomly and the result will be the same.

Okay, some of your classmates started to write code, and they wrote this kind of code

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

    }

Note that this is not possible, because although it is the same Random, each call to nextInt results in a different result.

It should be written as follows:

    @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]
    }

Two Random random seeds have the same value for the i r second nextInt.

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

Posted by Levan on Thu, 16 May 2019 21:06:51 -0700