如何对两个列表进行乱序处理,同时保持它们的一一对应的关系?

栏目: Java · 发布时间: 5年前

内容简介:已知我们有两个列表其中fileList和imgList中的元素是一一对应的。现在我们希望对两个列表进行随机排序,要求排序后它们依旧是一一对应的。

如何对两个列表进行乱序处理,同时保持它们的一一对应的关系?

已知我们有两个列表

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中的元素是一一对应的。

现在我们希望对两个列表进行随机排序,要求 排序 后它们依旧是一一对应的。

提示: 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 确实可以使得一个列表乱序,但是上面两次乱序后列表之间失去了一一对应的关系,所以是不行的。

那我们怎么解决呢?

方案一: 把它们绑定起来

我们之前的演示用例失败的原因是两次随机化的规则不一样,导致结果不能一一对应,那么我们现在可以

让它们一一绑定起来,构造出一个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]
    }

参考这样的代码。看起来很复杂,其实思路很简单。

  • 先把fileList第i个元素的值和imgList第i个元素的值绑定起来,构造出新的数组
  • 然后对着数组进行乱序,乱序完成后原理的两个list的对应依旧保持一致
  • 将list整理还原

方案2: 采取同样的方式随机化

我们来说一下Collections.shuffle 的原理。

当我们调用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/...


以上所述就是小编给大家介绍的《如何对两个列表进行乱序处理,同时保持它们的一一对应的关系?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web 2.0 Heroes

Web 2.0 Heroes

Bradley L. Jones / Wiley / 2008-04-14 / USD 24.99

Web 2.0 may be an elusive concept, but one thing is certain: using the Web as merely a means of retrieving and displaying information is history. Today?s Web is immediate, interactive, innovative. It ......一起来看看 《Web 2.0 Heroes》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具